Merge branch 'development' into Atom/santorac/RemixableMaterialTypes3_UpdatedStandardPbr
Signed-off-by: santorac <55155825+santorac@users.noreply.github.com>
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bfc2ef8c6dbf2fba078e27e4e94384099e090468e679327dd826a5cbf22b04ed
|
||||
size 1019
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:708b12d41229afab78e0f7d59097ae3de855fea8525a920c5c214fc0ce79f1bd
|
||||
size 1209
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fab63af9b50790dca25330058e70517987ea8bf11c00f9353dd951ebdbd1dbe5
|
||||
size 5008
|
||||
File diff suppressed because it is too large
Load Diff
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<Component
|
||||
Name="NetworkTestLevelEntityComponent"
|
||||
Namespace="AutomatedTesting"
|
||||
OverrideComponent="false"
|
||||
OverrideController="false"
|
||||
OverrideInclude=""
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<ComponentRelation Constraint="Required" HasController="true" Name="NetworkTransformComponent" Namespace="Multiplayer" Include="Multiplayer/Components/NetworkTransformComponent.h" />
|
||||
|
||||
<RemoteProcedure Name="AuthorityToClientNoParams_PlayFx" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="true" GenerateEventBindings="true" Description="" />
|
||||
|
||||
</Component>
|
||||
@@ -29,8 +29,6 @@
|
||||
<Param Type="float" Name="SomeFloat" />
|
||||
</RemoteProcedure>
|
||||
|
||||
<RemoteProcedure Name="AuthorityToClientNoParams_PlayFx" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="true" GenerateEventBindings="true" Description="" />
|
||||
|
||||
<RemoteProcedure Name="ServerToAuthority_DealDamage" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="true" GenerateEventBindings="true" Description="" >
|
||||
<Param Type="float" Name="damage" />
|
||||
</RemoteProcedure>
|
||||
|
||||
@@ -12,4 +12,5 @@ set(FILES
|
||||
Source/AutomatedTestingSystemComponent.cpp
|
||||
Source/AutomatedTestingSystemComponent.h
|
||||
Source/AutoGen/NetworkTestPlayerComponent.AutoComponent.xml
|
||||
Source/AutoGen/NetworkTestLevelEntityComponent.AutoComponent.xml
|
||||
)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6d6204c6730e5675791765ca194e9b1cbec282208e280507de830afc2805e5fa
|
||||
size 41127
|
||||
oid sha256:de0e6e480ece5b423222f4feacf56553d73713fe9afea8bbc9a2660a3cd54ec7
|
||||
size 1232
|
||||
|
||||
@@ -23,6 +23,10 @@ class TestAutomation(EditorTestSuite):
|
||||
|
||||
enable_prefab_system = True
|
||||
|
||||
@pytest.mark.test_case_id("C36529679")
|
||||
class AtomLevelLoadTest_Editor(EditorSharedTest):
|
||||
from Atom.tests import hydra_Atom_LevelLoadTest as test_module
|
||||
|
||||
@pytest.mark.test_case_id("C36525657")
|
||||
class AtomEditorComponents_BloomAdded(EditorSharedTest):
|
||||
from Atom.tests import hydra_AtomEditorComponents_BloomAdded as test_module
|
||||
|
||||
@@ -32,6 +32,8 @@ GLOBAL_ILLUMINATION_QUALITY = {
|
||||
'High': 2,
|
||||
}
|
||||
|
||||
# Level list used in Editor Level Load Test
|
||||
LEVEL_LIST = ["hermanubis", "hermanubis_high", "macbeth_shaderballs", "PbrMaterialChart", "ShadowTest", "Sponza"]
|
||||
|
||||
class AtomComponentProperties:
|
||||
"""
|
||||
@@ -195,11 +197,13 @@ class AtomComponentProperties:
|
||||
def entity_reference(property: str = 'name') -> str:
|
||||
"""
|
||||
Entity Reference component properties.
|
||||
- 'EntityIdReferences' component container of entityId references. Initially empty.
|
||||
:param property: From the last element of the property tree path. Default 'name' for component name string.
|
||||
:return: Full property path OR component name if no property specified.
|
||||
"""
|
||||
properties = {
|
||||
'name': 'Entity Reference',
|
||||
'EntityIdReferences': 'Controller|Configuration|EntityIdReferences',
|
||||
}
|
||||
return properties[property]
|
||||
|
||||
|
||||
+126
-25
@@ -9,37 +9,58 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
class Tests:
|
||||
creation_undo = (
|
||||
"UNDO Entity creation success",
|
||||
"UNDO Entity creation failed")
|
||||
"P0: UNDO Entity creation failed")
|
||||
creation_redo = (
|
||||
"REDO Entity creation success",
|
||||
"REDO Entity creation failed")
|
||||
"P0: REDO Entity creation failed")
|
||||
entity_reference_creation = (
|
||||
"Entity Reference Entity successfully created",
|
||||
"Entity Reference Entity failed to be created")
|
||||
"P0: Entity Reference Entity failed to be created")
|
||||
entity_reference_component = (
|
||||
"Entity has an Entity Reference component",
|
||||
"Entity failed to find Entity Reference component")
|
||||
"P0: Entity failed to find Entity Reference component")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
"P0: Failed to enter game mode")
|
||||
exit_game_mode = (
|
||||
"Exited game mode",
|
||||
"Couldn't exit game mode")
|
||||
"P0: Couldn't exit game mode")
|
||||
is_visible = (
|
||||
"Entity is visible",
|
||||
"Entity was not visible")
|
||||
"P0: Entity was not visible")
|
||||
is_hidden = (
|
||||
"Entity is hidden",
|
||||
"Entity was not hidden")
|
||||
"P0: Entity was not hidden")
|
||||
entity_deleted = (
|
||||
"Entity deleted",
|
||||
"Entity was not deleted")
|
||||
"P0: Entity was not deleted")
|
||||
deletion_undo = (
|
||||
"UNDO deletion success",
|
||||
"UNDO deletion failed")
|
||||
"P0: UNDO deletion failed")
|
||||
deletion_redo = (
|
||||
"REDO deletion success",
|
||||
"REDO deletion failed")
|
||||
"P0: REDO deletion failed")
|
||||
entity_id_references_is_container = (
|
||||
"EntityIdReferences is a container property",
|
||||
"P1: EntityIdReferences is NOT a container property")
|
||||
container_append = (
|
||||
"EntityIdReferences append succeeded",
|
||||
"P1: EntityIdReferences append did not succeed")
|
||||
container_add = (
|
||||
"EntityIdReferences add succeeded",
|
||||
"P1: EntityIdReferences add did not succeed")
|
||||
container_update = (
|
||||
"EntityIdReferences update succeeded",
|
||||
"P1: EntityIdReferences update did not succeed")
|
||||
container_remove = (
|
||||
"EntityIdReferences remove succeeded",
|
||||
"P1: EntityIdReferences remove did not succeed")
|
||||
container_reset = (
|
||||
"EntityIdReferences reset succeeded",
|
||||
"P1: EntityIdReferences reset did not succeed")
|
||||
entity_reference_component_removed = (
|
||||
"Entity Reference component removed from entity",
|
||||
"P1: Entity Reference component NOT removed from entity")
|
||||
|
||||
|
||||
def AtomEditorComponents_EntityReference_AddedToEntity():
|
||||
@@ -60,13 +81,21 @@ def AtomEditorComponents_EntityReference_AddedToEntity():
|
||||
2) Add Entity Reference component to Entity Reference entity.
|
||||
3) UNDO the entity creation and component addition.
|
||||
4) REDO the entity creation and component addition.
|
||||
5) Enter/Exit game mode.
|
||||
6) Test IsHidden.
|
||||
7) Test IsVisible.
|
||||
8) Delete Entity Reference entity.
|
||||
9) UNDO deletion.
|
||||
10) REDO deletion.
|
||||
11) Look for errors.
|
||||
5) 'EntityIdReferences' is a container property
|
||||
6) Append item to 'EntityIdReferences'
|
||||
7) Add item to 'EntityIdReferences'
|
||||
8) Update item in 'EntityIdReferences'
|
||||
9) Remove item from 'EntityIdReferences'
|
||||
10) Reset the container property then put one entity reference back for further tests
|
||||
11) Remove component
|
||||
12) UNDO component remove
|
||||
13) Enter/Exit game mode.
|
||||
14) Test IsHidden.
|
||||
15) Test IsVisible.
|
||||
16) Delete Entity Reference entity.
|
||||
17) UNDO deletion.
|
||||
18) REDO deletion.
|
||||
19) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
@@ -119,35 +148,107 @@ def AtomEditorComponents_EntityReference_AddedToEntity():
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, entity_reference_entity.exists())
|
||||
|
||||
# 5. Enter/Exit game mode.
|
||||
# Entities for EntityIdReferences tests
|
||||
test_1 = EditorEntity.create_editor_entity('test_1')
|
||||
test_2 = EditorEntity.create_editor_entity('test_2')
|
||||
test_3 = EditorEntity.create_editor_entity('test_3')
|
||||
|
||||
# 5. 'EntityIdReferences' is a container property
|
||||
Report.result(
|
||||
Tests.entity_id_references_is_container,
|
||||
entity_reference_component.is_property_container(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences')))
|
||||
|
||||
# 6. Append item to 'EntityIdReferences'
|
||||
entity_reference_component.append_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), test_1.id)
|
||||
Report.result(
|
||||
Tests.container_append,
|
||||
entity_reference_component.get_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), 0) == test_1.id)
|
||||
|
||||
# 7. Add item to 'EntityIdReferences'
|
||||
entity_reference_component.add_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), 1, test_1.id)
|
||||
Report.result(
|
||||
Tests.container_add,
|
||||
entity_reference_component.get_container_count(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences')) == 2)
|
||||
|
||||
# 8. Update item in 'EntityIdReferences'
|
||||
entity_reference_component.update_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), 1, test_2.id)
|
||||
Report.result(
|
||||
Tests.container_update,
|
||||
entity_reference_component.get_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), 1) == test_2.id)
|
||||
|
||||
# 9. Remove item from 'EntityIdReferences'
|
||||
entity_reference_component.append_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), test_3.id)
|
||||
count_before = entity_reference_component.get_container_count(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'))
|
||||
entity_reference_component.remove_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), 1)
|
||||
count_after = entity_reference_component.get_container_count(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'))
|
||||
Report.result(
|
||||
Tests.container_remove,
|
||||
((count_before == 3) and (count_after == 2) and
|
||||
(entity_reference_component.get_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), 1) == test_3.id)))
|
||||
|
||||
# 10. Reset the container property then put one entity reference back for further tests
|
||||
entity_reference_component.reset_container(AtomComponentProperties.entity_reference('EntityIdReferences'))
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(
|
||||
Tests.container_reset,
|
||||
entity_reference_component.get_container_count(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences')) == 0)
|
||||
entity_reference_component.append_container_item(
|
||||
AtomComponentProperties.entity_reference('EntityIdReferences'), test_1.id)
|
||||
|
||||
# 11. Remove component
|
||||
entity_reference_entity.remove_component(AtomComponentProperties.entity_reference())
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.entity_reference_component_removed, not entity_reference_entity.has_component(
|
||||
AtomComponentProperties.entity_reference()))
|
||||
|
||||
# 12. UNDO component remove
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.entity_reference_component, entity_reference_entity.has_component(
|
||||
AtomComponentProperties.entity_reference()))
|
||||
|
||||
# 13. Enter/Exit game mode.
|
||||
TestHelper.enter_game_mode(Tests.enter_game_mode)
|
||||
general.idle_wait_frames(1)
|
||||
TestHelper.exit_game_mode(Tests.exit_game_mode)
|
||||
|
||||
# 6. Test IsHidden.
|
||||
# 14. Test IsHidden.
|
||||
entity_reference_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, entity_reference_entity.is_hidden() is True)
|
||||
|
||||
# 7. Test IsVisible.
|
||||
# 15. Test IsVisible.
|
||||
entity_reference_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, entity_reference_entity.is_visible() is True)
|
||||
|
||||
# 8. Delete Entity Reference entity.
|
||||
# 16. Delete Entity Reference entity.
|
||||
entity_reference_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not entity_reference_entity.exists())
|
||||
|
||||
# 9. UNDO deletion.
|
||||
# 17. UNDO deletion.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_undo, entity_reference_entity.exists())
|
||||
|
||||
# 10. REDO deletion.
|
||||
# 18. REDO deletion.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_redo, not entity_reference_entity.exists())
|
||||
|
||||
# 11. Look for errors and asserts.
|
||||
# 19. Look for errors and asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
def Atom_LevelLoadTest():
|
||||
"""
|
||||
Summary:
|
||||
Loads all graphics levels within the AutomatedTesting project in editor. For each level this script will verify that
|
||||
the level loads, and can enter/exit gameplay without crashing the editor.
|
||||
|
||||
Test setup:
|
||||
- Store all available levels in a list.
|
||||
- Set up a for loop to run all checks for each level.
|
||||
|
||||
Expected Behavior:
|
||||
Test verifies that each level loads, enters/exits game mode, and reports success for all test actions.
|
||||
|
||||
Test Steps for each level:
|
||||
1) Create tuple with level load success and failure messages
|
||||
2) Open the level using the python test tools command
|
||||
3) Verify level is loaded using a separate command, and report success/failure
|
||||
4) Enter gameplay and report result using a tuple
|
||||
5) Exit Gameplay and report result using a tuple
|
||||
6) Look for errors or asserts.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
from Atom.atom_utils.atom_constants import LEVEL_LIST
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
|
||||
for level in LEVEL_LIST:
|
||||
|
||||
# 1. Create tuple with level load success and failure messages
|
||||
level_check_tuple = (f"loaded {level}", f"failed to load {level}")
|
||||
|
||||
# 2. Open the level using the python test tools command
|
||||
TestHelper.init_idle()
|
||||
TestHelper.open_level("Graphics", level)
|
||||
|
||||
# 3. Verify level is loaded using a separate command, and report success/failure
|
||||
Report.result(level_check_tuple, level == general.get_current_level_name())
|
||||
|
||||
# 4. Enter gameplay and report result using a tuple
|
||||
enter_game_mode_tuple = (f"{level} entered gameplay successfully ", f"{level} failed to enter gameplay")
|
||||
TestHelper.enter_game_mode(enter_game_mode_tuple)
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
# 5. Exit gameplay and report result using a tuple
|
||||
exit_game_mode_tuple = (f"{level} exited gameplay successfully ", f"{level} failed to exit gameplay")
|
||||
TestHelper.exit_game_mode(exit_game_mode_tuple)
|
||||
|
||||
|
||||
# 6. Look for errors or asserts.
|
||||
TestHelper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0)
|
||||
for error_info in error_tracer.errors:
|
||||
Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}")
|
||||
for assert_info in error_tracer.asserts:
|
||||
Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Atom_LevelLoadTest)
|
||||
+5
-6
@@ -473,12 +473,11 @@ class EditorEntity:
|
||||
:param component_names: List of component names to remove
|
||||
:return: None
|
||||
"""
|
||||
type_ids = EditorComponent.get_type_ids(component_names, EditorEntityType.GAME)
|
||||
for type_id in type_ids:
|
||||
remove_outcome = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", self.id, [type_id])
|
||||
assert (
|
||||
remove_outcome.IsSuccess()
|
||||
), f"Failure: could not remove component from '{self.get_name()}'"
|
||||
component_ids = [component.id for component in self.get_components_of_type(component_names)]
|
||||
remove_success = editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", component_ids)
|
||||
assert (
|
||||
remove_success
|
||||
), f"Failure: could not remove component from entity '{self.get_name()}'"
|
||||
|
||||
def get_components_of_type(self, component_names: list) -> List[EditorComponent]:
|
||||
"""
|
||||
|
||||
+34
-34
@@ -48,8 +48,8 @@ def wait_for_propagation():
|
||||
# This is a helper class which contains some of the useful information about a prefab instance.
|
||||
class PrefabInstance:
|
||||
|
||||
def __init__(self, prefab_file_name: str = None, container_entity: EditorEntity = None):
|
||||
self.prefab_file_name: str = prefab_file_name
|
||||
def __init__(self, prefab_file_path: str = None, container_entity: EditorEntity = None):
|
||||
self.prefab_file_path: str = prefab_file_path
|
||||
self.container_entity: EditorEntity = container_entity
|
||||
|
||||
def __eq__(self, other):
|
||||
@@ -66,7 +66,7 @@ class PrefabInstance:
|
||||
See if this instance is valid to be used with other prefab operations.
|
||||
:return: Whether the target instance is valid or not.
|
||||
"""
|
||||
return self.container_entity.id.IsValid() and self.prefab_file_name in Prefab.existing_prefabs
|
||||
return self.container_entity.id.IsValid() and self.prefab_file_path in Prefab.existing_prefabs
|
||||
|
||||
def has_editor_prefab_component(self) -> bool:
|
||||
"""
|
||||
@@ -131,7 +131,7 @@ class PrefabInstance:
|
||||
has_correct_parent = reparented_container_entity_parent_id.ToString() == parent_entity_id.ToString()
|
||||
assert has_correct_parent, "Prefab Instance reparented is *not* under the expected parent entity"
|
||||
|
||||
current_instance_prefab = Prefab.get_prefab(self.prefab_file_name)
|
||||
current_instance_prefab = Prefab.get_prefab(self.prefab_file_path)
|
||||
current_instance_prefab.instances.remove(self)
|
||||
|
||||
self.container_entity = reparented_container_entity
|
||||
@@ -161,46 +161,48 @@ class Prefab:
|
||||
:param file_path: A unique file path of the target prefab.
|
||||
:return: Whether the target prefab is loaded or not.
|
||||
"""
|
||||
return file_path in Prefab.existing_prefabs
|
||||
|
||||
for entry in Prefab.existing_prefabs:
|
||||
Report.info(f"PrefabPath: '{entry}'")
|
||||
|
||||
return get_prefab_file_path(file_path) in Prefab.existing_prefabs
|
||||
|
||||
@classmethod
|
||||
def prefab_exists(cls, file_path: str) -> bool:
|
||||
"""
|
||||
Check if a prefab exists in the directory for files of prefab tests.
|
||||
:param file_name: A unique file name of the target prefab.
|
||||
:param file_path: A unique file path of the target prefab.
|
||||
:return: Whether the target prefab exists or not.
|
||||
"""
|
||||
return path.exists(get_prefab_file_path(file_path))
|
||||
|
||||
@classmethod
|
||||
def get_prefab(cls, file_name: str) -> Prefab:
|
||||
def get_prefab(cls, file_path: str) -> Prefab:
|
||||
"""
|
||||
Return a prefab which can be used immediately.
|
||||
:param file_name: A unique file name of the target prefab.
|
||||
:param file_path: A unique file path of the target prefab.
|
||||
:return: The prefab with given file name.
|
||||
"""
|
||||
assert file_name, "Received an empty file_name"
|
||||
if Prefab.is_prefab_loaded(file_name):
|
||||
return Prefab.existing_prefabs[file_name]
|
||||
assert file_path, "Received an empty file_path"
|
||||
if Prefab.is_prefab_loaded(file_path):
|
||||
return Prefab.existing_prefabs[get_prefab_file_path(file_path)]
|
||||
else:
|
||||
assert Prefab.prefab_exists(file_name), f"Attempted to get a prefab \"{file_name}\" that doesn't exist"
|
||||
new_prefab = Prefab(file_name)
|
||||
Prefab.existing_prefabs[file_name] = Prefab(file_name)
|
||||
assert Prefab.prefab_exists(file_path), f"Attempted to get a prefab \"{file_path}\" that doesn't exist"
|
||||
new_prefab = Prefab(file_path)
|
||||
Prefab.existing_prefabs[new_prefab.file_path] = new_prefab
|
||||
return new_prefab
|
||||
|
||||
@classmethod
|
||||
def create_prefab(cls, entities: list[EditorEntity], file_name: str, prefab_instance_name: str=None) -> tuple(Prefab, PrefabInstance):
|
||||
def create_prefab(cls, entities: list[EditorEntity], file_path: str, prefab_instance_name: str=None) -> tuple(Prefab, PrefabInstance):
|
||||
"""
|
||||
Create a prefab in memory and return it. The very first instance of this prefab will also be created.
|
||||
:param entities: The entities that should form the new prefab (along with their descendants).
|
||||
:param file_name: A unique file name of new prefab.
|
||||
:param prefab_instance_name: A name for the very first instance generated while prefab creation. The default instance name is the same as file_name.
|
||||
:param file_path: A unique file path for new prefab.
|
||||
:param prefab_instance_name: A name for the very first instance generated while prefab creation. The default instance name is the same as the file name in file_path.
|
||||
:return: Created Prefab object and the very first PrefabInstance object owned by the prefab.
|
||||
"""
|
||||
assert not Prefab.is_prefab_loaded(file_name), f"Can't create Prefab '{file_name}' since the prefab already exists"
|
||||
assert not Prefab.is_prefab_loaded(file_path), f"Can't create Prefab '{file_path}' since the prefab already exists"
|
||||
|
||||
new_prefab = Prefab(file_name)
|
||||
new_prefab = Prefab(file_path)
|
||||
entity_ids = [entity.id for entity in entities]
|
||||
create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', entity_ids, new_prefab.file_path)
|
||||
assert create_prefab_result.IsSuccess(), f"Prefab operation 'CreatePrefab' failed. Error: {create_prefab_result.GetError()}"
|
||||
@@ -210,15 +212,14 @@ class Prefab:
|
||||
children_entity_ids = container_entity.get_children_ids()
|
||||
|
||||
assert len(children_entity_ids) == len(entities), f"Entity count of created prefab instance does *not* match the count of given entities."
|
||||
|
||||
if prefab_instance_name:
|
||||
container_entity.set_name(prefab_instance_name)
|
||||
|
||||
|
||||
wait_for_propagation()
|
||||
|
||||
new_prefab_instance = PrefabInstance(file_name, EditorEntity(container_entity_id))
|
||||
new_prefab_instance = PrefabInstance(new_prefab.file_path, EditorEntity(container_entity_id))
|
||||
if prefab_instance_name:
|
||||
new_prefab_instance.container_entity.set_name(prefab_instance_name)
|
||||
new_prefab.instances.add(new_prefab_instance)
|
||||
Prefab.existing_prefabs[file_name] = new_prefab
|
||||
Prefab.existing_prefabs[new_prefab.file_path] = new_prefab
|
||||
return new_prefab, new_prefab_instance
|
||||
|
||||
@classmethod
|
||||
@@ -250,7 +251,7 @@ class Prefab:
|
||||
assert False, "Not all entities and descendants in target prefabs are deleted."
|
||||
|
||||
for instance in prefab_instances:
|
||||
instance_deleted_prefab = Prefab.get_prefab(instance.prefab_file_name)
|
||||
instance_deleted_prefab = Prefab.get_prefab(instance.prefab_file_path)
|
||||
instance_deleted_prefab.instances.remove(instance)
|
||||
instance = PrefabInstance()
|
||||
|
||||
@@ -290,8 +291,7 @@ class Prefab:
|
||||
prefab_file_path = prefab.PrefabPublicRequestBus(bus.Broadcast, 'GetOwningInstancePrefabPath', duplicate_container_entity_id)
|
||||
assert prefab_file_path, "Returned file path should *not* be empty."
|
||||
|
||||
prefab_file_name = Path(prefab_file_path).stem
|
||||
duplicate_instance_prefab = Prefab.get_prefab(prefab_file_name)
|
||||
duplicate_instance_prefab = Prefab.get_prefab(prefab_file_path)
|
||||
duplicate_instance = PrefabInstance(prefab_file_path, EditorEntity(duplicate_container_entity_id))
|
||||
duplicate_instance_prefab.instances.add(duplicate_instance)
|
||||
duplicate_instances.append(duplicate_instance)
|
||||
@@ -324,7 +324,7 @@ class Prefab:
|
||||
|
||||
wait_for_propagation()
|
||||
|
||||
instance_owner_prefab = Prefab.get_prefab(prefab_instance.prefab_file_name)
|
||||
instance_owner_prefab = Prefab.get_prefab(prefab_instance.prefab_file_path)
|
||||
instance_owner_prefab.instances.remove(prefab_instance)
|
||||
prefab_instance = PrefabInstance()
|
||||
|
||||
@@ -346,13 +346,13 @@ class Prefab:
|
||||
container_entity_id = instantiate_prefab_result.GetValue()
|
||||
container_entity = EditorEntity(container_entity_id)
|
||||
|
||||
if name:
|
||||
container_entity.set_name(name)
|
||||
|
||||
wait_for_propagation()
|
||||
|
||||
new_prefab_instance = PrefabInstance(self.file_path, EditorEntity(container_entity_id))
|
||||
assert not new_prefab_instance in self.instances, "This prefab instance is already existed before this instantiation."
|
||||
assert not new_prefab_instance in self.instances, "This prefab instance already existed before this instantiation."
|
||||
if name:
|
||||
new_prefab_instance.container_entity.set_name(name)
|
||||
|
||||
self.instances.add(new_prefab_instance)
|
||||
|
||||
assert new_prefab_instance.is_at_position(prefab_position), "This prefab instance is *not* at expected position."
|
||||
|
||||
@@ -35,3 +35,7 @@ class TestAutomation(TestAutomationBase):
|
||||
def test_Multiplayer_AutoComponent_RPC(self, request, workspace, editor, launcher_platform):
|
||||
from .tests import Multiplayer_AutoComponent_RPC as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_Multiplayer_SimpleNetworkLevelEntity(self, request, workspace, editor, launcher_platform):
|
||||
from .tests import Multiplayer_SimpleNetworkLevelEntity as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
@@ -62,15 +62,16 @@ def Multiplayer_AutoComponent_RPC():
|
||||
Report.critical_result(TestSuccessFailTuples.find_network_player, player_id.IsValid())
|
||||
|
||||
# 4) Check the editor logs for expected and unexpected log output
|
||||
# Authority->Autonomous RPC
|
||||
PLAYERID_RPC_WAIT_TIME_SECONDS = 1.0 # The player id is sent from the server as soon as the player script is spawned. 1 second should be more than enough time to send/receive that RPC.
|
||||
helper.succeed_if_log_line_found('EditorServer', 'Script: AutoComponent_RPC: Sending client PlayerNumber 1', section_tracer.prints, PLAYERID_RPC_WAIT_TIME_SECONDS)
|
||||
helper.succeed_if_log_line_found('Script', "AutoComponent_RPC: I'm Player #1", section_tracer.prints, PLAYERID_RPC_WAIT_TIME_SECONDS)
|
||||
|
||||
# Uncomment once editor game-play mode supports level entities with net-binding
|
||||
#PLAYFX_RPC_WAIT_TIME_SECONDS = 1.1 # The server will send an RPC to play an fx on the client every second.
|
||||
#helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC_NetLevelEntity Activated on entity: NetLevelEntity", section_tracer.prints, PLAYFX_RPC_WAIT_TIME_SECONDS)
|
||||
#helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC_NetLevelEntity: Authority sending RPC to play some fx.", section_tracer.prints, PLAYFX_RPC_WAIT_TIME_SECONDS)
|
||||
#helper.succeed_if_log_line_found('Script', "AutoComponent_RPC_NetLevelEntity: I'm a client playing some superficial fx.", section_tracer.prints, PLAYFX_RPC_WAIT_TIME_SECONDS)
|
||||
# Authority->Client RPC
|
||||
PLAYFX_RPC_WAIT_TIME_SECONDS = 1.1 # The server will send an RPC to play an fx on the client every second.
|
||||
helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC_NetLevelEntity Activated on entity: NetLevelEntity", section_tracer.prints, PLAYFX_RPC_WAIT_TIME_SECONDS)
|
||||
helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC_NetLevelEntity: Authority sending RPC to play some fx.", section_tracer.prints, PLAYFX_RPC_WAIT_TIME_SECONDS)
|
||||
helper.succeed_if_log_line_found('Script', "AutoComponent_RPC_NetLevelEntity: I'm a client playing some fx.", section_tracer.prints, PLAYFX_RPC_WAIT_TIME_SECONDS)
|
||||
|
||||
|
||||
# Exit game mode
|
||||
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
# Test Case Title : Check that level entities with network bindings are properly replicated.
|
||||
# Note: This test should be ran on a fresh editor run; some bugs with spawnables occur only on the first editor play-mode.
|
||||
|
||||
|
||||
# fmt: off
|
||||
class TestSuccessFailTuples():
|
||||
enter_game_mode = ("Entered game mode", "Failed to enter game mode")
|
||||
exit_game_mode = ("Exited game mode", "Couldn't exit game mode")
|
||||
find_network_player = ("Found network player", "Couldn't find network player")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def Multiplayer_SimpleNetworkLevelEntity():
|
||||
r"""
|
||||
Summary:
|
||||
Test to make sure that network entities in a level function and are replicated to clients as expected
|
||||
|
||||
Level Description:
|
||||
- Static
|
||||
1. NetLevelEntity. This is a networked entity which has a script attached which prints logs to ensure it's replicated.
|
||||
|
||||
|
||||
Expected Outcome:
|
||||
We should see logs stating that the net-sync'd level entity exists on both server and client.
|
||||
|
||||
:return:
|
||||
"""
|
||||
import azlmbr.legacy.general as general
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import Tracer
|
||||
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole
|
||||
|
||||
level_name = "SimpleNetworkLevelEntity"
|
||||
player_prefab_name = "Player"
|
||||
player_prefab_path = f"levels/multiplayer/{level_name}/{player_prefab_name}.network.spawnable"
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# 1) Open Level
|
||||
helper.open_level("Multiplayer", level_name)
|
||||
|
||||
with Tracer() as section_tracer:
|
||||
# 2) Enter game mode
|
||||
helper.multiplayer_enter_game_mode(TestSuccessFailTuples.enter_game_mode, player_prefab_path.lower())
|
||||
|
||||
# 3) Make sure the network player was spawned
|
||||
player_id = general.find_game_entity(player_prefab_name)
|
||||
Report.critical_result(TestSuccessFailTuples.find_network_player, player_id.IsValid())
|
||||
|
||||
# 4) Check the editor logs for network spawnable errors
|
||||
ATTEMPTING_INVALID_NETSPAWN_WAIT_TIME_SECONDS = 0.0 # The editor will try to net-spawn its networked level entity before it's even a client. Make sure this didn't happen.
|
||||
helper.fail_if_log_line_found('NetworkEntityManager', "RequestNetSpawnableInstantiation: Requested spawnable Root.network.spawnable doesn't exist in the NetworkSpawnableLibrary. Please make sure it is a network spawnable", section_tracer.errors, ATTEMPTING_INVALID_NETSPAWN_WAIT_TIME_SECONDS)
|
||||
|
||||
# 5) Ensure the script graph attached to the level entity is running on the server
|
||||
SCRIPTGRAPH_ENABLED_WAIT_TIME_SECONDS = 0.25
|
||||
helper.succeed_if_log_line_found('EditorServer', "Script: SimpleNetworkLevelEntity: On Graph Start", section_tracer.prints, SCRIPTGRAPH_ENABLED_WAIT_TIME_SECONDS)
|
||||
|
||||
|
||||
# Exit game mode
|
||||
helper.exit_game_mode(TestSuccessFailTuples.exit_game_mode)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Multiplayer_SimpleNetworkLevelEntity)
|
||||
@@ -38,6 +38,10 @@ class TestAutomation(TestAutomationBase):
|
||||
from Prefab.tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_InstantiatePrefab_FromCreatedPrefabWithSingleEntity(self, request, workspace, editor, launcher_platform):
|
||||
from Prefab.tests.instantiate_prefab import InstantiatePrefab_FromCreatedPrefabWithSingleEntity as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_DeletePrefab_ContainingASingleEntity(self, request, workspace, editor, launcher_platform):
|
||||
from Prefab.tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
@@ -45,8 +45,12 @@ class TestAutomationNoAutoTestMode(EditorTestSuite):
|
||||
class test_InstantiatePrefab_ContainingASingleEntity(EditorSharedTest):
|
||||
from .tests.instantiate_prefab import InstantiatePrefab_ContainingASingleEntity as test_module
|
||||
|
||||
class test_InstantiatePrefab_FromCreatedPrefabWithSingleEntity(EditorSharedTest):
|
||||
from .tests.instantiate_prefab import InstantiatePrefab_FromCreatedPrefabWithSingleEntity as test_module
|
||||
|
||||
class test_DeletePrefab_ContainingASingleEntity(EditorSharedTest):
|
||||
from .tests.delete_prefab import DeletePrefab_ContainingASingleEntity as test_module
|
||||
|
||||
class test_DuplicatePrefab_ContainingASingleEntity(EditorSharedTest):
|
||||
from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module
|
||||
from .tests.duplicate_prefab import DuplicatePrefab_ContainingASingleEntity as test_module
|
||||
|
||||
+2
-1
@@ -13,7 +13,8 @@ def CreatePrefab_UnderAnEntity():
|
||||
Test is successful if the new instanced prefab of the child has the parent entity id
|
||||
"""
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab'
|
||||
from pathlib import Path
|
||||
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
+2
-1
@@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
def CreatePrefab_WithSingleEntity():
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab'
|
||||
from pathlib import Path
|
||||
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report
|
||||
|
||||
+2
-1
@@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
def DeletePrefab_ContainingASingleEntity():
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab'
|
||||
from pathlib import Path
|
||||
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
+3
-2
@@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
def DetachPrefab_UnderAnotherPrefab():
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab2'
|
||||
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab2'
|
||||
from pathlib import Path
|
||||
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
|
||||
WHEEL_PREFAB_FILE_NAME = Path(__file__).stem + 'wheel_prefab'
|
||||
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
|
||||
|
||||
+2
-1
@@ -7,7 +7,8 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
def DuplicatePrefab_ContainingASingleEntity():
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab'
|
||||
from pathlib import Path
|
||||
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
def InstantiatePrefab_FromCreatedPrefabWithSingleEntity():
|
||||
|
||||
from pathlib import Path
|
||||
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
import Prefab.tests.PrefabTestUtils as prefab_test_utils
|
||||
|
||||
prefab_test_utils.open_base_tests_level()
|
||||
|
||||
# Creates a new entity at the root level
|
||||
car_entity = EditorEntity.create_editor_entity()
|
||||
car_prefab_entities = [car_entity]
|
||||
|
||||
# Creates a prefab from the new entity
|
||||
car_prefab, car_prefab_instance = Prefab.create_prefab(car_prefab_entities, CAR_PREFAB_FILE_NAME)
|
||||
|
||||
# Instantiate another instance and verify
|
||||
car_prefab_instance_2 = car_prefab.instantiate()
|
||||
assert car_prefab_instance_2.is_valid(), "Failed to instantiate prefab"
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(InstantiatePrefab_FromCreatedPrefabWithSingleEntity)
|
||||
+3
-2
@@ -7,8 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
def ReparentPrefab_UnderAnotherPrefab():
|
||||
|
||||
CAR_PREFAB_FILE_NAME = 'car_prefab'
|
||||
WHEEL_PREFAB_FILE_NAME = 'wheel_prefab'
|
||||
from pathlib import Path
|
||||
CAR_PREFAB_FILE_NAME = Path(__file__).stem + 'car_prefab'
|
||||
WHEEL_PREFAB_FILE_NAME = Path(__file__).stem + 'wheel_prefab'
|
||||
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
|
||||
|
||||
+2
-3
@@ -93,7 +93,7 @@ def Terrain_World_ConfigurationWorks():
|
||||
# 5) Set the base Terrain World values
|
||||
world_bounds_max = azmath.Vector3(1100.0, 1100.0, 1100.0)
|
||||
world_bounds_min = azmath.Vector3(10.0, 10.0, 10.0)
|
||||
height_query_resolution = azmath.Vector2(1.0, 1.0)
|
||||
height_query_resolution = 1.0
|
||||
hydra.set_component_property_value(terrain_world_component, "Configuration|World Bounds (Max)", world_bounds_max)
|
||||
hydra.set_component_property_value(terrain_world_component, "Configuration|World Bounds (Min)", world_bounds_min)
|
||||
hydra.set_component_property_value(terrain_world_component, "Configuration|Height Query Resolution (m)", height_query_resolution)
|
||||
@@ -148,7 +148,7 @@ def Terrain_World_ConfigurationWorks():
|
||||
|
||||
# 13) Check height value is the expected one when query resolution is changed
|
||||
testpoint = terrain.TerrainDataRequestBus(bus.Broadcast, 'GetHeightFromFloats', 10.5, 10.5, CLAMP)
|
||||
height_query_resolution = azmath.Vector2(0.5, 0.5)
|
||||
height_query_resolution = 0.5
|
||||
hydra.set_component_property_value(terrain_world_component, "Configuration|Height Query Resolution (m)", height_query_resolution)
|
||||
general.idle_wait_frames(1)
|
||||
testpoint2 = terrain.TerrainDataRequestBus(bus.Broadcast, 'GetHeightFromFloats', 10.5, 10.5, CLAMP)
|
||||
@@ -165,4 +165,3 @@ if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Terrain_World_ConfigurationWorks)
|
||||
|
||||
|
||||
@@ -19,12 +19,16 @@ def find_nodes_matching_entity_component(component_name, entity_id):
|
||||
:param entity_id: The entity ID to search for the given component node on
|
||||
:return List of matching nodes
|
||||
"""
|
||||
component_type_id = hydra.get_component_type_id(component_name)
|
||||
component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity_id,
|
||||
hydra.get_component_type_id(component_name))
|
||||
component_type_id)
|
||||
|
||||
if component.IsSuccess():
|
||||
component_id = component.GetValue()
|
||||
component_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
|
||||
component_id)
|
||||
if component_node:
|
||||
print(f"{component_name} node found on entity {entity_id.ToString()}")
|
||||
else:
|
||||
print(f"Failed to find {component_name} node on entity {entity_id.ToString()}")
|
||||
return component_node
|
||||
|
||||
@@ -38,7 +38,7 @@ def Menus_FileMenuOptions_Work():
|
||||
("Save As",),
|
||||
("Save Level Statistics",),
|
||||
("Edit Project Settings",),
|
||||
#("Edit Platform Settings",), Temporarily disabled due to https://github.com/o3de/o3de/issues/6604
|
||||
("Edit Platform Settings",),
|
||||
("New Project",),
|
||||
("Open Project",),
|
||||
("Show Log File",),
|
||||
|
||||
@@ -43,7 +43,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Main_Optimized
|
||||
TEST_SERIAL
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main_Optimized.py
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/TestSuite_Main.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
|
||||
+1
-2
@@ -68,8 +68,7 @@ def AreaNodes_DependentComponentsAdded():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+1
-3
@@ -58,7 +58,6 @@ def AreaNodes_EntityCreatedOnNodeAdd():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -67,8 +66,7 @@ def AreaNodes_EntityCreatedOnNodeAdd():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+2
-3
@@ -59,8 +59,8 @@ def AreaNodes_EntityRemovedOnNodeDelete():
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -73,8 +73,7 @@ def AreaNodes_EntityRemovedOnNodeDelete():
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+14
-22
@@ -1,15 +1,14 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
slice_instantiated = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
prefab_instantiated = (
|
||||
"Prefab instantiated successfully",
|
||||
"Failed to instantiate prefab"
|
||||
)
|
||||
lc_entity_found = (
|
||||
"LandscapeCanvas entity found",
|
||||
@@ -24,7 +23,7 @@ class Tests:
|
||||
"Failed to find Distribution Filter component on BushSpawner entity"
|
||||
)
|
||||
existing_graph_opened = (
|
||||
"Opened existing graph from slice",
|
||||
"Opened existing graph from prefab",
|
||||
"Failed to open existing graph"
|
||||
)
|
||||
dist_filter_node_found = (
|
||||
@@ -66,10 +65,8 @@ def ComponentUpdates_UpdateGraph():
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of
|
||||
Landscape Canvas.
|
||||
|
||||
Expected Behavior:
|
||||
Graphs properly reflect component changes made to entities outside of Landscape Canvas.
|
||||
|
||||
Test Steps:
|
||||
1. Open Level
|
||||
2. Find LandscapeCanvas named entity
|
||||
@@ -83,41 +80,36 @@ def ComponentUpdates_UpdateGraph():
|
||||
9. Add a new entity with unique name as a child of the Landscape Canvas entity
|
||||
10. Add a Box Shape component to the new child entity
|
||||
11. Ensure Box Shape node is present on the open graph
|
||||
|
||||
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
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
import azlmbr.prefab as prefab
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open a simple level and instantiate LC_BushFlowerBlender.slice
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
# Open a simple level and instantiate BushFlowerBlender.prefab
|
||||
hydra.open_base_level()
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
|
||||
test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab")
|
||||
prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path,
|
||||
entity.EntityId(), position)
|
||||
Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess())
|
||||
|
||||
# Find root entity in the loaded level
|
||||
search_filter = entity.SearchFilter()
|
||||
@@ -126,8 +118,8 @@ def ComponentUpdates_UpdateGraph():
|
||||
# Allow a few seconds for matching entity to be found
|
||||
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
|
||||
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
slice_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component
|
||||
Report.critical_result(Tests.lc_entity_found, slice_root_id.IsValid())
|
||||
prefab_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component
|
||||
Report.critical_result(Tests.lc_entity_found, prefab_root_id.IsValid())
|
||||
|
||||
# Find the BushSpawner entity
|
||||
search_filter.names = ["BushSpawner"]
|
||||
@@ -147,7 +139,7 @@ def ComponentUpdates_UpdateGraph():
|
||||
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_root_id)
|
||||
Report.critical_result(Tests.existing_graph_opened, open_graph.IsValid())
|
||||
|
||||
# Verify that Distribution Filter node is present on the graph
|
||||
|
||||
+1
-3
@@ -45,11 +45,9 @@ def Component_AddedRemoved():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Create an Entity at the root of the level
|
||||
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
+1
-2
@@ -59,8 +59,7 @@ def Edit_DisabledNodeDuplication():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+15
-22
@@ -1,15 +1,14 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
slice_spawned = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
prefab_instantiated = (
|
||||
"Prefab instantiated successfully",
|
||||
"Failed to instantiate prefab"
|
||||
)
|
||||
lc_entity_found = (
|
||||
"Landscape Canvas entity found",
|
||||
@@ -31,31 +30,28 @@ class Tests:
|
||||
"Vegetation Layer Spawner node was successfully removed",
|
||||
"Failed to remove Vegetation Layer Spawner node"
|
||||
)
|
||||
def Edit_UndoNodeDelete_SliceEntity():
|
||||
|
||||
|
||||
def Edit_UndoNodeDelete_PrefabEntity():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies Editor stability after undoing the deletion of nodes on a slice entity.
|
||||
|
||||
This test verifies Editor stability after undoing the deletion of nodes on a prefab entity.
|
||||
Expected Behavior:
|
||||
Editor remains stable and free of crashes.
|
||||
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Instantiate a slice with a Landscape Canvas setup
|
||||
2) Instantiate a prefab with a Landscape Canvas setup
|
||||
3) Find a specific node on the graph, and delete it
|
||||
4) Restore the node with Undo
|
||||
|
||||
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
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
@@ -63,25 +59,23 @@ def Edit_UndoNodeDelete_SliceEntity():
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
import azlmbr.prefab as prefab
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Instantiate slice
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
Report.result(Tests.slice_spawned, test_slice.IsValid())
|
||||
test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab")
|
||||
prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path,
|
||||
entity.EntityId(), position)
|
||||
Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess())
|
||||
|
||||
# Find root entity in the loaded level
|
||||
search_filter = entity.SearchFilter()
|
||||
@@ -134,5 +128,4 @@ def Edit_UndoNodeDelete_SliceEntity():
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Edit_UndoNodeDelete_SliceEntity)
|
||||
|
||||
Report.start_test(Edit_UndoNodeDelete_PrefabEntity)
|
||||
+1
-3
@@ -76,7 +76,6 @@ def GradientMixer_NodeConstruction():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -85,8 +84,7 @@ def GradientMixer_NodeConstruction():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+1
-3
@@ -58,7 +58,6 @@ def GradientModifierNodes_EntityCreatedOnNodeAdd():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -67,8 +66,7 @@ def GradientModifierNodes_EntityCreatedOnNodeAdd():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+2
-3
@@ -58,8 +58,8 @@ def GradientModifierNodes_EntityRemovedOnNodeDelete():
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -72,8 +72,7 @@ def GradientModifierNodes_EntityRemovedOnNodeDelete():
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+1
-3
@@ -60,7 +60,6 @@ def GradientNodes_DependentComponentsAdded():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -69,8 +68,7 @@ def GradientNodes_DependentComponentsAdded():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+1
-3
@@ -58,7 +58,6 @@ def GradientNodes_EntityCreatedOnNodeAdd():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -67,8 +66,7 @@ def GradientNodes_EntityCreatedOnNodeAdd():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+2
-3
@@ -58,8 +58,8 @@ def GradientNodes_EntityRemovedOnNodeDelete():
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -72,8 +72,7 @@ def GradientNodes_EntityRemovedOnNodeDelete():
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+2
-3
@@ -51,8 +51,8 @@ def GraphClosed_OnEntityDelete():
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -61,8 +61,7 @@ def GraphClosed_OnEntityDelete():
|
||||
newRootEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+3
-4
@@ -51,14 +51,13 @@ def GraphClosed_OnLevelChange():
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
@@ -73,7 +72,7 @@ def GraphClosed_OnLevelChange():
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Open a different level, which should close any open Landscape Canvas graphs
|
||||
general.open_level_no_prompt('WhiteBox/EmptyLevel')
|
||||
general.open_level_no_prompt('Base')
|
||||
|
||||
# Make sure the graph we created is now closed
|
||||
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
|
||||
+2
-3
@@ -51,8 +51,8 @@ def GraphClosed_TabbedGraphClosesIndependently():
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editor_id = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -65,8 +65,7 @@ def GraphClosed_TabbedGraphClosesIndependently():
|
||||
return graph_open
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+22
-25
@@ -1,18 +1,17 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
slice_instantiated = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
prefab_instantiated = (
|
||||
"Prefab instantiated successfully",
|
||||
"Failed to instantiate prefab"
|
||||
)
|
||||
existing_graph_opened = (
|
||||
"Opened existing graph from slice",
|
||||
"Opened existing graph from prefab",
|
||||
"Failed to open existing graph"
|
||||
)
|
||||
node_removed = (
|
||||
@@ -37,13 +36,11 @@ def GraphUpdates_UpdateComponent():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that components are properly updated as nodes are added/removed/updated.
|
||||
|
||||
Expected Behavior:
|
||||
Landscape Canvas node CRUD properly updates component entities.
|
||||
|
||||
Test Steps:
|
||||
1. Open Level.
|
||||
2. Open the graph on LC_BushFlowerBlender.slice
|
||||
2. Open the graph on BushFlowerBlender.prefab
|
||||
3. Find the Rotation Modifier node on the BushSpawner entity
|
||||
4. Delete the Rotation Modifier node
|
||||
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
|
||||
@@ -51,18 +48,15 @@ def GraphUpdates_UpdateComponent():
|
||||
7. Ensure BushSpawner entity is deleted
|
||||
8. Change connection from second Rotation Modifier node to a different Gradient
|
||||
9. Ensure Gradient reference on component is updated
|
||||
|
||||
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
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
@@ -70,39 +64,37 @@ def GraphUpdates_UpdateComponent():
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
import azlmbr.prefab as prefab
|
||||
|
||||
import automatedtesting_shared.landscape_canvas_utils as lc
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open a simple level and instantiate LC_BushFlowerBlender.slice
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
# Open a simple level and instantiate BushFlowerBlender.prefab
|
||||
hydra.open_base_level()
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
|
||||
test_prefab_path = os.path.join("Assets", "Prefabs", "BushFlowerBlender.prefab")
|
||||
prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', test_prefab_path,
|
||||
entity.EntityId(), position)
|
||||
Report.critical_result(Tests.prefab_instantiated, prefab_result.IsSuccess())
|
||||
|
||||
# Search for root entity to ensure slice is loaded
|
||||
# Search for root entity to ensure prefab is loaded
|
||||
search_filter = entity.SearchFilter()
|
||||
search_filter.names = ["LandscapeCanvas"]
|
||||
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
|
||||
prefab_lc_root = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)[0]
|
||||
|
||||
# Find needed entities in the loaded level
|
||||
slice_root_id = hydra.find_entity_by_name('LandscapeCanvas')
|
||||
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
|
||||
flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner')
|
||||
inverted_perlin_noise_id = hydra.find_entity_by_name('Invert')
|
||||
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root)
|
||||
Report.critical_result(Tests.existing_graph_opened, open_graph_id.IsValid())
|
||||
|
||||
# Find the Rotation Modifier node on the BushSpawner entity
|
||||
@@ -110,6 +102,7 @@ def GraphUpdates_UpdateComponent():
|
||||
|
||||
# Remove the Rotation Modifier node
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0])
|
||||
general.idle_wait_frames(2)
|
||||
|
||||
# Verify node was removed
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
|
||||
@@ -121,14 +114,18 @@ def GraphUpdates_UpdateComponent():
|
||||
Report.result(Tests.component_removed, not has_rotation_modifier)
|
||||
|
||||
# Find the Vegetation Layer Spawner node on the BushSpawner entity
|
||||
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root)
|
||||
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
|
||||
|
||||
# Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0])
|
||||
general.idle_wait_frames(2)
|
||||
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
|
||||
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
|
||||
Report.result(Tests.entity_deleted, not bush_spawner_id)
|
||||
Report.result(Tests.entity_deleted, not layer_spawner_node and not bush_spawner_id)
|
||||
|
||||
# Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node
|
||||
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', prefab_lc_root)
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id)
|
||||
invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id)
|
||||
|
||||
@@ -137,7 +134,7 @@ def GraphUpdates_UpdateComponent():
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0],
|
||||
outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot)
|
||||
|
||||
general.idle_wait(1.0) # Add a small wait to ensure component property has time to update
|
||||
general.idle_wait_frames(2) # Add a small wait to ensure component property has time to update
|
||||
|
||||
# Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set
|
||||
rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier')
|
||||
|
||||
+1
-3
@@ -64,7 +64,6 @@ def LayerBlender_NodeConstruction():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -73,8 +72,7 @@ def LayerBlender_NodeConstruction():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+1
-3
@@ -63,7 +63,6 @@ def LayerExtenderNodes_ComponentEntitySync():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -72,8 +71,7 @@ def LayerExtenderNodes_ComponentEntitySync():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+1
-3
@@ -60,7 +60,6 @@ def NewGraph_CreatedSuccessfully():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -69,8 +68,7 @@ def NewGraph_CreatedSuccessfully():
|
||||
new_root_entity_id = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# with the new graph has our Landscape Canvas component automatically added
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
prefab_created = (
|
||||
"Prefab created successfully",
|
||||
"Failed to create prefab"
|
||||
)
|
||||
prefab_instantiated = (
|
||||
"Prefab instantiated successfully",
|
||||
"Failed to instantiate prefab"
|
||||
)
|
||||
|
||||
|
||||
def Prefab_CreateInstantiate():
|
||||
"""
|
||||
Summary:
|
||||
A prefab containing the LandscapeCanvas component can be created/instantiated.
|
||||
Expected Result:
|
||||
Prefab is created/processed/instantiated successfully and free of errors/warnings.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Create a new entity with a Landscape Canvas component
|
||||
3) Create a prefab of the new entity
|
||||
4) Instantiate a new copy of the prefab
|
||||
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 azlmbr.math as math
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
from editor_python_test_tools.prefab_utils import Prefab
|
||||
|
||||
# Open an existing simple level
|
||||
hydra.open_base_level()
|
||||
|
||||
# Create entity with Landscape Canvas component
|
||||
position = math.Vector3(512.0, 512.0, 32.0)
|
||||
landscape_canvas = hydra.Entity("landscape_canvas_entity")
|
||||
landscape_canvas.create_entity(position, ["Landscape Canvas"])
|
||||
|
||||
# Create in-memory prefab from the created entity
|
||||
lc_prefab_filename = "LC_PrefabTest"
|
||||
lc_prefab, lc_prefab_instance = Prefab.create_prefab([landscape_canvas], lc_prefab_filename)
|
||||
|
||||
# Verify if prefab is created
|
||||
helper.wait_for_condition(lambda: lc_prefab.is_prefab_loaded(lc_prefab_filename), 5.0)
|
||||
Report.result(Tests.prefab_created, lc_prefab.is_prefab_loaded(lc_prefab_filename))
|
||||
|
||||
# Instantiate prefab
|
||||
lc_prefab_instance2 = lc_prefab.instantiate()
|
||||
helper.wait_for_condition(lambda: lc_prefab_instance2.has_editor_prefab_component(), 5.0)
|
||||
Report.result(Tests.prefab_instantiated, lc_prefab_instance2.has_editor_prefab_component())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Prefab_CreateInstantiate)
|
||||
+2
-5
@@ -58,7 +58,6 @@ def ShapeNodes_EntityCreatedOnNodeAdd():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -66,10 +65,8 @@ def ShapeNodes_EntityCreatedOnNodeAdd():
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
# Open an existing simple level
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
+2
-3
@@ -58,8 +58,8 @@ def ShapeNodes_EntityRemovedOnNodeDelete():
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -72,8 +72,7 @@ def ShapeNodes_EntityRemovedOnNodeDelete():
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
slice_created = (
|
||||
"Slice created successfully",
|
||||
"Failed to create slice"
|
||||
)
|
||||
slice_instantiated = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
)
|
||||
|
||||
|
||||
def Slice_CreateInstantiate():
|
||||
"""
|
||||
Summary:
|
||||
A slice containing the LandscapeCanvas component can be created/instantiated.
|
||||
|
||||
Expected Result:
|
||||
Slice is created/processed/instantiated successfully and free of errors/warnings.
|
||||
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Create a new entity with a Landscape Canvas component
|
||||
3) Create a slice of the new entity
|
||||
4) Instantiate a new copy of the slice
|
||||
|
||||
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
|
||||
|
||||
import azlmbr.math as math
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.slice as slice
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def path_is_valid_asset(asset_path):
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
|
||||
return asset_id.invoke("IsValid")
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Create entity with Landscape Canvas component
|
||||
position = math.Vector3(512.0, 512.0, 32.0)
|
||||
landscape_canvas = hydra.Entity("landscape_canvas_entity")
|
||||
landscape_canvas.create_entity(position, ["Landscape Canvas"])
|
||||
|
||||
# Create slice from the created entity
|
||||
slice_path = os.path.join("slices", "TestSlice.slice")
|
||||
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", landscape_canvas.id, slice_path)
|
||||
|
||||
# Verify if slice is created
|
||||
helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
|
||||
Report.result(Tests.slice_created, path_is_valid_asset(slice_path))
|
||||
|
||||
# Instantiate slice
|
||||
transform = math.Transform_CreateIdentity()
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", slice_path, math.Uuid(), False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, "InstantiateSliceFromAssetId", asset_id, transform)
|
||||
helper.wait_for_condition(lambda: test_slice.IsValid(), 5.0)
|
||||
Report.result(Tests.slice_instantiated, test_slice.IsValid())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Slice_CreateInstantiate)
|
||||
+1
-3
@@ -67,7 +67,6 @@ def SlotConnections_UpdateComponentReferences():
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
@@ -101,8 +100,7 @@ def SlotConnections_UpdateComponentReferences():
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
|
||||
@@ -1,29 +1,88 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
|
||||
from base import TestAutomationBase
|
||||
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
|
||||
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
def test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
|
||||
|
||||
def test_LandscapeCanvas_GradientMixer_NodeConstruction(self, request, workspace, editor, launcher_platform):
|
||||
class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest):
|
||||
from .EditorScripts import Component_AddedRemoved as test_module
|
||||
|
||||
class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest):
|
||||
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
|
||||
|
||||
class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest):
|
||||
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
|
||||
|
||||
class test_LandscapeCanvas_Edit_UndoNodeDelete_PrefabEntity(EditorSharedTest):
|
||||
from .EditorScripts import Edit_UndoNodeDelete_PrefabEntity as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest):
|
||||
from .EditorScripts import GradientMixer_NodeConstruction as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
|
||||
class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_OnLevelChange as test_module
|
||||
|
||||
class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_TabbedGraph as test_module
|
||||
|
||||
@pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/7141" "https://github.com/o3de/o3de/issues/4872")
|
||||
class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest):
|
||||
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
|
||||
|
||||
class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest):
|
||||
from .EditorScripts import LayerBlender_NodeConstruction as test_module
|
||||
|
||||
class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest):
|
||||
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
|
||||
|
||||
class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest):
|
||||
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
|
||||
|
||||
class test_LandscapeCanvas_Prefab_CreateInstantiate(EditorSharedTest):
|
||||
from .EditorScripts import Prefab_CreateInstantiate as test_module
|
||||
|
||||
class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
|
||||
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
|
||||
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
import ly_test_tools._internal.pytest_plugin as internal_plugin
|
||||
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomationWithPrefabSystemEnabled(EditorTestSuite):
|
||||
|
||||
class test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
enable_prefab_system = False
|
||||
|
||||
class test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
|
||||
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest):
|
||||
from .EditorScripts import GradientMixer_NodeConstruction as test_module
|
||||
|
||||
class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest):
|
||||
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
|
||||
|
||||
class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest):
|
||||
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
|
||||
|
||||
class test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(EditorSharedTest):
|
||||
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
|
||||
|
||||
class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest):
|
||||
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
|
||||
|
||||
class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest):
|
||||
from .EditorScripts import Component_AddedRemoved as test_module
|
||||
|
||||
class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_OnLevelChange as test_module
|
||||
|
||||
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
|
||||
class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_TabbedGraph as test_module
|
||||
|
||||
class test_LandscapeCanvas_Slice_CreateInstantiate(EditorSingleTest):
|
||||
from .EditorScripts import Slice_CreateInstantiate as test_module
|
||||
# Custom teardown to remove slice asset created during test
|
||||
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
|
||||
"TestSlice.slice")], True, True)
|
||||
|
||||
class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
@pytest.mark.skipif("debug" == os.path.basename(internal_plugin.build_directory),
|
||||
reason="https://github.com/o3de/o3de/issues/4872")
|
||||
class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest):
|
||||
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
|
||||
|
||||
class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest):
|
||||
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
|
||||
|
||||
class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest):
|
||||
from .EditorScripts import LayerBlender_NodeConstruction as test_module
|
||||
|
||||
class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
|
||||
@@ -1,121 +0,0 @@
|
||||
"""
|
||||
Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
|
||||
from base import TestAutomationBase
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def remove_test_slice(request, workspace, project):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, True)
|
||||
|
||||
def teardown():
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True,
|
||||
True)
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
|
||||
def test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_Edit_DisabledNodeDuplication(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_Component_AddedRemoved(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import Component_AddedRemoved as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphClosed_OnLevelChange as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
|
||||
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphClosed_TabbedGraph as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_Slice_CreateInstantiate(self, request, workspace, editor, remove_test_slice, launcher_platform):
|
||||
from .EditorScripts import Slice_CreateInstantiate as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_GraphUpdates_UpdateComponents(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_ComponentUpdates_UpdateGraph(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import LayerBlender_NodeConstruction as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
|
||||
def test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module, enable_prefab_system=False)
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:de0e6e480ece5b423222f4feacf56553d73713fe9afea8bbc9a2660a3cd54ec7
|
||||
size 1232
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6d6204c6730e5675791765ca194e9b1cbec282208e280507de830afc2805e5fa
|
||||
size 41127
|
||||
oid sha256:de0e6e480ece5b423222f4feacf56553d73713fe9afea8bbc9a2660a3cd54ec7
|
||||
size 1232
|
||||
|
||||
@@ -568,22 +568,10 @@
|
||||
"$type": "EditorScriptCanvasComponent",
|
||||
"Id": 14750978061505735417,
|
||||
"m_name": "GlobalGameData",
|
||||
"m_assetHolder": {
|
||||
"m_asset": {
|
||||
"assetId": {
|
||||
"guid": "{B16589A0-EA01-56BC-8141-91A3967FB95F}"
|
||||
},
|
||||
"assetHint": "levels/multiplayer/autocomponent_rpc/globalgamedata.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"runtimeDataIsValid": true,
|
||||
"runtimeDataOverrides": {
|
||||
"source": {
|
||||
"assetId": {
|
||||
"guid": "{B16589A0-EA01-56BC-8141-91A3967FB95F}"
|
||||
},
|
||||
"assetHint": "levels/multiplayer/autocomponent_rpc/globalgamedata.scriptcanvas"
|
||||
}
|
||||
"sourceHandle": {
|
||||
"id": "{B16589A0-EA01-56BC-8141-91A3967FB95F}",
|
||||
"path": "levels/multiplayer/autocomponent_rpc/globalgamedata.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"Component_[16436925042043744033]": {
|
||||
@@ -636,6 +624,13 @@
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 12302672911455629152
|
||||
},
|
||||
"Component_[12517591696100736853]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 12517591696100736853,
|
||||
"m_template": {
|
||||
"$type": "AutomatedTesting::NetworkTestLevelEntityComponent"
|
||||
}
|
||||
},
|
||||
"Component_[14169903623243423134]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 14169903623243423134
|
||||
@@ -644,13 +639,6 @@
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14607413934411389854
|
||||
},
|
||||
"Component_[15396284312416541768]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 15396284312416541768,
|
||||
"m_template": {
|
||||
"$type": "Multiplayer::LocalPredictionPlayerInputComponent"
|
||||
}
|
||||
},
|
||||
"Component_[15494977028055234270]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 15494977028055234270
|
||||
@@ -682,22 +670,10 @@
|
||||
"$type": "EditorScriptCanvasComponent",
|
||||
"Id": 7256163899440301540,
|
||||
"m_name": "AutoComponent_RPC_NetLevelEntity",
|
||||
"m_assetHolder": {
|
||||
"m_asset": {
|
||||
"assetId": {
|
||||
"guid": "{1D517006-AC01-5ECA-AE66-0E007871F0CD}"
|
||||
},
|
||||
"assetHint": "levels/multiplayer/autocomponent_rpc/autocomponent_rpc_netlevelentity.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"runtimeDataIsValid": true,
|
||||
"runtimeDataOverrides": {
|
||||
"source": {
|
||||
"assetId": {
|
||||
"guid": "{1D517006-AC01-5ECA-AE66-0E007871F0CD}"
|
||||
},
|
||||
"assetHint": "levels/multiplayer/autocomponent_rpc/autocomponent_rpc_netlevelentity.scriptcanvas"
|
||||
}
|
||||
"sourceHandle": {
|
||||
"id": "{1D517006-AC01-5ECA-AE66-0E007871F0CD}",
|
||||
"path": "levels/multiplayer/autocomponent_rpc/autocomponent_rpc_netlevelentity.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"Component_[731336627222243355]": {
|
||||
@@ -730,13 +706,6 @@
|
||||
"$type": "NetBindComponent"
|
||||
}
|
||||
},
|
||||
"Component_[9816897251206708579]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 9816897251206708579,
|
||||
"m_template": {
|
||||
"$type": "AutomatedTesting::NetworkTestPlayerComponent"
|
||||
}
|
||||
},
|
||||
"Component_[9880860858035405475]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 9880860858035405475
|
||||
|
||||
+3079
-6
File diff suppressed because it is too large
Load Diff
+889
-542
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"ContainerEntity": {
|
||||
"Id": "ContainerEntity",
|
||||
"Name": "Player",
|
||||
"Components": {
|
||||
"Component_[10626669441604518614]": {
|
||||
"$type": "EditorPrefabComponent",
|
||||
"Id": 10626669441604518614
|
||||
},
|
||||
"Component_[15284109105474306026]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 15284109105474306026
|
||||
},
|
||||
"Component_[1884250773831675865]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 1884250773831675865
|
||||
},
|
||||
"Component_[3027124663594865592]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 3027124663594865592
|
||||
},
|
||||
"Component_[3314300526416851038]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 3314300526416851038,
|
||||
"Child Entity Order": [
|
||||
"Entity_[1340484004600]"
|
||||
]
|
||||
},
|
||||
"Component_[5583377204116393478]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 5583377204116393478
|
||||
},
|
||||
"Component_[5897955848881060165]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 5897955848881060165
|
||||
},
|
||||
"Component_[6405389103180201977]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 6405389103180201977,
|
||||
"Parent Entity": ""
|
||||
},
|
||||
"Component_[7695912346724202125]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 7695912346724202125
|
||||
},
|
||||
"Component_[775363990560391238]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 775363990560391238
|
||||
},
|
||||
"Component_[904355854135646057]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 904355854135646057
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entities": {
|
||||
"Entity_[1340484004600]": {
|
||||
"Id": "Entity_[1340484004600]",
|
||||
"Name": "Player",
|
||||
"Components": {
|
||||
"Component_[12294726333564087591]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 12294726333564087591
|
||||
},
|
||||
"Component_[13587084088242540786]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 13587084088242540786,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 6819443882832501114
|
||||
},
|
||||
{
|
||||
"ComponentId": 4337571454344109612,
|
||||
"SortIndex": 1
|
||||
},
|
||||
{
|
||||
"ComponentId": 16457408099527309065,
|
||||
"SortIndex": 2
|
||||
},
|
||||
{
|
||||
"ComponentId": 5577505593558922067,
|
||||
"SortIndex": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[14335168881008289852]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 14335168881008289852
|
||||
},
|
||||
"Component_[16308902899170829847]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 16308902899170829847
|
||||
},
|
||||
"Component_[16457408099527309065]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 16457408099527309065,
|
||||
"m_template": {
|
||||
"$type": "Multiplayer::NetworkTransformComponent"
|
||||
}
|
||||
},
|
||||
"Component_[16541569566865026527]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 16541569566865026527
|
||||
},
|
||||
"Component_[2002761223483048905]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 2002761223483048905
|
||||
},
|
||||
"Component_[4337571454344109612]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 4337571454344109612,
|
||||
"m_template": {
|
||||
"$type": "NetBindComponent"
|
||||
}
|
||||
},
|
||||
"Component_[477591477979440744]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 477591477979440744
|
||||
},
|
||||
"Component_[5577505593558922067]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 5577505593558922067,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}",
|
||||
"subId": 284780167
|
||||
},
|
||||
"assetHint": "models/sphere.azmodel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[5828214869455694702]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5828214869455694702
|
||||
},
|
||||
"Component_[6819443882832501114]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 6819443882832501114,
|
||||
"Parent Entity": "ContainerEntity"
|
||||
},
|
||||
"Component_[8838623765985560328]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 8838623765985560328
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+580
@@ -0,0 +1,580 @@
|
||||
{
|
||||
"ContainerEntity": {
|
||||
"Id": "Entity_[1146574390643]",
|
||||
"Name": "Level",
|
||||
"Components": {
|
||||
"Component_[10641544592923449938]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 10641544592923449938
|
||||
},
|
||||
"Component_[12039882709170782873]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 12039882709170782873
|
||||
},
|
||||
"Component_[12265484671603697631]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 12265484671603697631
|
||||
},
|
||||
"Component_[14126657869720434043]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 14126657869720434043,
|
||||
"Child Entity Order": [
|
||||
"Entity_[1176639161715]",
|
||||
"Entity_[806656324666]"
|
||||
]
|
||||
},
|
||||
"Component_[15230859088967841193]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 15230859088967841193,
|
||||
"Parent Entity": ""
|
||||
},
|
||||
"Component_[16239496886950819870]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 16239496886950819870
|
||||
},
|
||||
"Component_[5688118765544765547]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 5688118765544765547
|
||||
},
|
||||
"Component_[6545738857812235305]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 6545738857812235305
|
||||
},
|
||||
"Component_[7247035804068349658]": {
|
||||
"$type": "EditorPrefabComponent",
|
||||
"Id": 7247035804068349658
|
||||
},
|
||||
"Component_[9307224322037797205]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 9307224322037797205
|
||||
},
|
||||
"Component_[9562516168917670048]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 9562516168917670048
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entities": {
|
||||
"Entity_[1155164325235]": {
|
||||
"Id": "Entity_[1155164325235]",
|
||||
"Name": "Sun",
|
||||
"Components": {
|
||||
"Component_[10440557478882592717]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 10440557478882592717
|
||||
},
|
||||
"Component_[13620450453324765907]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 13620450453324765907
|
||||
},
|
||||
"Component_[2134313378593666258]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 2134313378593666258
|
||||
},
|
||||
"Component_[234010807770404186]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 234010807770404186
|
||||
},
|
||||
"Component_[2970359110423865725]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 2970359110423865725
|
||||
},
|
||||
"Component_[3722854130373041803]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 3722854130373041803
|
||||
},
|
||||
"Component_[5992533738676323195]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5992533738676323195
|
||||
},
|
||||
"Component_[7378860763541895402]": {
|
||||
"$type": "AZ::Render::EditorDirectionalLightComponent",
|
||||
"Id": 7378860763541895402,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"Intensity": 1.0,
|
||||
"CameraEntityId": "",
|
||||
"ShadowFilterMethod": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[7892834440890947578]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 7892834440890947578,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
0.0,
|
||||
0.0,
|
||||
13.487043380737305
|
||||
],
|
||||
"Rotate": [
|
||||
-76.13099670410156,
|
||||
-0.847000002861023,
|
||||
-15.8100004196167
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[8599729549570828259]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 8599729549570828259
|
||||
},
|
||||
"Component_[952797371922080273]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 952797371922080273
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[1159459292531]": {
|
||||
"Id": "Entity_[1159459292531]",
|
||||
"Name": "Ground",
|
||||
"Components": {
|
||||
"Component_[11701138785793981042]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 11701138785793981042
|
||||
},
|
||||
"Component_[12260880513256986252]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 12260880513256986252
|
||||
},
|
||||
"Component_[13711420870643673468]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 13711420870643673468
|
||||
},
|
||||
"Component_[138002849734991713]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 138002849734991713
|
||||
},
|
||||
"Component_[16578565737331764849]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 16578565737331764849,
|
||||
"Parent Entity": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[16919232076966545697]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 16919232076966545697
|
||||
},
|
||||
"Component_[5182430712893438093]": {
|
||||
"$type": "EditorMaterialComponent",
|
||||
"Id": 5182430712893438093
|
||||
},
|
||||
"Component_[5675108321710651991]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 5675108321710651991,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
|
||||
"subId": 277889906
|
||||
},
|
||||
"assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[5681893399601237518]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 5681893399601237518
|
||||
},
|
||||
"Component_[592692962543397545]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 592692962543397545
|
||||
},
|
||||
"Component_[7090012899106946164]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 7090012899106946164
|
||||
},
|
||||
"Component_[9410832619875640998]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 9410832619875640998
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[1163754259827]": {
|
||||
"Id": "Entity_[1163754259827]",
|
||||
"Name": "Camera",
|
||||
"Components": {
|
||||
"Component_[11895140916889160460]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 11895140916889160460
|
||||
},
|
||||
"Component_[16880285896855930892]": {
|
||||
"$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
|
||||
"Id": 16880285896855930892,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"Field of View": 55.0,
|
||||
"EditorEntityId": 9021008456353177945
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[17187464423780271193]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 17187464423780271193
|
||||
},
|
||||
"Component_[17495696818315413311]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 17495696818315413311
|
||||
},
|
||||
"Component_[18086214374043522055]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 18086214374043522055,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
-2.3000001907348633,
|
||||
-3.9368600845336914,
|
||||
1.0
|
||||
],
|
||||
"Rotate": [
|
||||
-2.050307512283325,
|
||||
1.9552897214889526,
|
||||
-43.623355865478516
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[18387556550380114975]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 18387556550380114975
|
||||
},
|
||||
"Component_[2654521436129313160]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 2654521436129313160
|
||||
},
|
||||
"Component_[5265045084611556958]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5265045084611556958
|
||||
},
|
||||
"Component_[7169798125182238623]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 7169798125182238623
|
||||
},
|
||||
"Component_[7255796294953281766]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 7255796294953281766,
|
||||
"m_template": {
|
||||
"$type": "FlyCameraInputComponent"
|
||||
}
|
||||
},
|
||||
"Component_[8866210352157164042]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 8866210352157164042
|
||||
},
|
||||
"Component_[9129253381063760879]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 9129253381063760879
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[1168049227123]": {
|
||||
"Id": "Entity_[1168049227123]",
|
||||
"Name": "Grid",
|
||||
"Components": {
|
||||
"Component_[11443347433215807130]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 11443347433215807130
|
||||
},
|
||||
"Component_[11779275529534764488]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 11779275529534764488
|
||||
},
|
||||
"Component_[14249419413039427459]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14249419413039427459
|
||||
},
|
||||
"Component_[15448581635946161318]": {
|
||||
"$type": "AZ::Render::EditorGridComponent",
|
||||
"Id": 15448581635946161318,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"primarySpacing": 4.0,
|
||||
"primaryColor": [
|
||||
0.501960813999176,
|
||||
0.501960813999176,
|
||||
0.501960813999176
|
||||
],
|
||||
"secondarySpacing": 0.5,
|
||||
"secondaryColor": [
|
||||
0.250980406999588,
|
||||
0.250980406999588,
|
||||
0.250980406999588
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[1843303322527297409]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 1843303322527297409
|
||||
},
|
||||
"Component_[380249072065273654]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 380249072065273654,
|
||||
"Parent Entity": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[7476660583684339787]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 7476660583684339787
|
||||
},
|
||||
"Component_[7557626501215118375]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 7557626501215118375
|
||||
},
|
||||
"Component_[7984048488947365511]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 7984048488947365511
|
||||
},
|
||||
"Component_[8118181039276487398]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 8118181039276487398
|
||||
},
|
||||
"Component_[9189909764215270515]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 9189909764215270515
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[1176639161715]": {
|
||||
"Id": "Entity_[1176639161715]",
|
||||
"Name": "Atom Default Environment",
|
||||
"Components": {
|
||||
"Component_[10757302973393310045]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 10757302973393310045,
|
||||
"Parent Entity": "Entity_[1146574390643]"
|
||||
},
|
||||
"Component_[14505817420424255464]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14505817420424255464,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 10757302973393310045
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[14988041764659020032]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 14988041764659020032
|
||||
},
|
||||
"Component_[15808690248755038124]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 15808690248755038124
|
||||
},
|
||||
"Component_[15900837685796817138]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 15900837685796817138
|
||||
},
|
||||
"Component_[3298767348226484884]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 3298767348226484884
|
||||
},
|
||||
"Component_[4076975109609220594]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 4076975109609220594
|
||||
},
|
||||
"Component_[5679760548946028854]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5679760548946028854
|
||||
},
|
||||
"Component_[5855590796136709437]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 5855590796136709437,
|
||||
"Child Entity Order": [
|
||||
"Entity_[1155164325235]",
|
||||
"Entity_[1180934129011]",
|
||||
"Entity_[1168049227123]",
|
||||
"Entity_[1163754259827]",
|
||||
"Entity_[1159459292531]"
|
||||
]
|
||||
},
|
||||
"Component_[9277695270015777859]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 9277695270015777859
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[1180934129011]": {
|
||||
"Id": "Entity_[1180934129011]",
|
||||
"Name": "Global Sky",
|
||||
"Components": {
|
||||
"Component_[11231930600558681245]": {
|
||||
"$type": "AZ::Render::EditorHDRiSkyboxComponent",
|
||||
"Id": 11231930600558681245,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"CubemapAsset": {
|
||||
"assetId": {
|
||||
"guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
|
||||
"subId": 1000
|
||||
},
|
||||
"assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[11980494120202836095]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 11980494120202836095
|
||||
},
|
||||
"Component_[1428633914413949476]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 1428633914413949476
|
||||
},
|
||||
"Component_[14936200426671614999]": {
|
||||
"$type": "AZ::Render::EditorImageBasedLightComponent",
|
||||
"Id": 14936200426671614999,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"diffuseImageAsset": {
|
||||
"assetId": {
|
||||
"guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
|
||||
"subId": 3000
|
||||
},
|
||||
"assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
|
||||
},
|
||||
"specularImageAsset": {
|
||||
"assetId": {
|
||||
"guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
|
||||
"subId": 2000
|
||||
},
|
||||
"assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[14994774102579326069]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 14994774102579326069
|
||||
},
|
||||
"Component_[15417479889044493340]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 15417479889044493340
|
||||
},
|
||||
"Component_[15826613364991382688]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 15826613364991382688
|
||||
},
|
||||
"Component_[1665003113283562343]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 1665003113283562343
|
||||
},
|
||||
"Component_[3704934735944502280]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 3704934735944502280
|
||||
},
|
||||
"Component_[5698542331457326479]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 5698542331457326479
|
||||
},
|
||||
"Component_[6644513399057217122]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 6644513399057217122,
|
||||
"Parent Entity": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[931091830724002070]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 931091830724002070
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[806656324666]": {
|
||||
"Id": "Entity_[806656324666]",
|
||||
"Name": "NetEntity",
|
||||
"Components": {
|
||||
"Component_[10272449525230713408]": {
|
||||
"$type": "EditorScriptCanvasComponent",
|
||||
"Id": 10272449525230713408,
|
||||
"m_name": "SimpleNetworkLevelEntity.scriptcanvas",
|
||||
"runtimeDataIsValid": true,
|
||||
"runtimeDataOverrides": {
|
||||
"source": {
|
||||
"id": "{C8F17F94-1225-5FFB-A89F-7C5546FF9DD2}",
|
||||
"path": "C:/prj/o3de/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"sourceHandle": {
|
||||
"id": "{C8F17F94-1225-5FFB-A89F-7C5546FF9DD2}",
|
||||
"path": "C:/prj/o3de/AutomatedTesting/Levels/Multiplayer/SimpleNetworkLevelEntity/SimpleNetworkLevelEntity.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"Component_[12604265186664827718]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 12604265186664827718
|
||||
},
|
||||
"Component_[12971088454284742740]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 12971088454284742740
|
||||
},
|
||||
"Component_[13637345797899267673]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 13637345797899267673
|
||||
},
|
||||
"Component_[14691827217729577086]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 14691827217729577086
|
||||
},
|
||||
"Component_[17587769654029626028]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 17587769654029626028,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}",
|
||||
"subId": 284780167
|
||||
},
|
||||
"assetHint": "models/sphere.azmodel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[3583806849894952953]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 3583806849894952953
|
||||
},
|
||||
"Component_[3992057042487734240]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 3992057042487734240
|
||||
},
|
||||
"Component_[4205899043279271481]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 4205899043279271481,
|
||||
"m_template": {
|
||||
"$type": "Multiplayer::NetworkTransformComponent"
|
||||
}
|
||||
},
|
||||
"Component_[4416976521140638764]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 4416976521140638764
|
||||
},
|
||||
"Component_[4951162661196722987]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 4951162661196722987
|
||||
},
|
||||
"Component_[57491843687005111]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 57491843687005111,
|
||||
"Parent Entity": "Entity_[1146574390643]",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
-0.010266244411468506,
|
||||
0.09999752044677734,
|
||||
0.4922151565551758
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[7427201282284088219]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 7427201282284088219
|
||||
},
|
||||
"Component_[9767802049284917261]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 9767802049284917261,
|
||||
"m_template": {
|
||||
"$type": "NetBindComponent"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "ScriptCanvasData",
|
||||
"ClassData": {
|
||||
"m_scriptCanvas": {
|
||||
"Id": {
|
||||
"id": 5227099818161821361
|
||||
},
|
||||
"Name": "Script Canvas Graph",
|
||||
"Components": {
|
||||
"Component_[14745706451564425001]": {
|
||||
"$type": "EditorGraphVariableManagerComponent",
|
||||
"Id": 14745706451564425001
|
||||
},
|
||||
"Component_[6188351434280490877]": {
|
||||
"$type": "EditorGraph",
|
||||
"Id": 6188351434280490877,
|
||||
"m_graphData": {
|
||||
"m_nodes": [
|
||||
{
|
||||
"Id": {
|
||||
"id": 1181151842701
|
||||
},
|
||||
"Name": "SC-Node(Print)",
|
||||
"Components": {
|
||||
"Component_[11204048151736284490]": {
|
||||
"$type": "Print",
|
||||
"Id": 11204048151736284490,
|
||||
"Slots": [
|
||||
{
|
||||
"id": {
|
||||
"m_id": "{A417FF98-493E-4DE6-AD3A-E7A1848661E4}"
|
||||
},
|
||||
"contracts": [
|
||||
{
|
||||
"$type": "SlotTypeContract"
|
||||
}
|
||||
],
|
||||
"slotName": "In",
|
||||
"toolTip": "Input signal",
|
||||
"Descriptor": {
|
||||
"ConnectionType": 1,
|
||||
"SlotType": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": {
|
||||
"m_id": "{38BC2AB1-7654-407E-9903-4B5D77EDB6F3}"
|
||||
},
|
||||
"contracts": [
|
||||
{
|
||||
"$type": "SlotTypeContract"
|
||||
}
|
||||
],
|
||||
"slotName": "Out",
|
||||
"Descriptor": {
|
||||
"ConnectionType": 2,
|
||||
"SlotType": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"m_format": "SimpleNetworkLevelEntity: On Graph Start\n",
|
||||
"m_unresolvedString": [
|
||||
"SimpleNetworkLevelEntity: On Graph Start\n"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": {
|
||||
"id": 811784655245
|
||||
},
|
||||
"Name": "SC-Node(Start)",
|
||||
"Components": {
|
||||
"Component_[2986280341871382503]": {
|
||||
"$type": "Start",
|
||||
"Id": 2986280341871382503,
|
||||
"Slots": [
|
||||
{
|
||||
"id": {
|
||||
"m_id": "{61FBEFC6-23BA-4A53-89BF-D0D0E834608C}"
|
||||
},
|
||||
"contracts": [
|
||||
{
|
||||
"$type": "SlotTypeContract"
|
||||
}
|
||||
],
|
||||
"slotName": "Out",
|
||||
"toolTip": "Signaled when the entity that owns this graph is fully activated.",
|
||||
"Descriptor": {
|
||||
"ConnectionType": 2,
|
||||
"SlotType": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"m_connections": [
|
||||
{
|
||||
"Id": {
|
||||
"id": 2521181639053
|
||||
},
|
||||
"Name": "srcEndpoint=(On Graph Start: Out), destEndpoint=(Print: In)",
|
||||
"Components": {
|
||||
"Component_[16295428600276205051]": {
|
||||
"$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection",
|
||||
"Id": 16295428600276205051,
|
||||
"sourceEndpoint": {
|
||||
"nodeId": {
|
||||
"id": 811784655245
|
||||
},
|
||||
"slotId": {
|
||||
"m_id": "{61FBEFC6-23BA-4A53-89BF-D0D0E834608C}"
|
||||
}
|
||||
},
|
||||
"targetEndpoint": {
|
||||
"nodeId": {
|
||||
"id": 1181151842701
|
||||
},
|
||||
"slotId": {
|
||||
"m_id": "{A417FF98-493E-4DE6-AD3A-E7A1848661E4}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"m_assetType": "{00000000-0000-0000-D033-B2489A010000}",
|
||||
"versionData": {
|
||||
"_grammarVersion": 1,
|
||||
"_runtimeVersion": 1,
|
||||
"_fileVersion": 1
|
||||
},
|
||||
"GraphCanvasData": [
|
||||
{
|
||||
"Key": {
|
||||
"id": 811784655245
|
||||
},
|
||||
"Value": {
|
||||
"ComponentData": {
|
||||
"{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
|
||||
"$type": "NodeSaveData"
|
||||
},
|
||||
"{328FF15C-C302-458F-A43D-E1794DE0904E}": {
|
||||
"$type": "GeneralNodeTitleComponentSaveData",
|
||||
"PaletteOverride": "TimeNodeTitlePalette"
|
||||
},
|
||||
"{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
|
||||
"$type": "GeometrySaveData",
|
||||
"Position": [
|
||||
340.0,
|
||||
180.0
|
||||
]
|
||||
},
|
||||
"{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
|
||||
"$type": "StylingComponentSaveData"
|
||||
},
|
||||
"{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
|
||||
"$type": "PersistentIdComponentSaveData",
|
||||
"PersistentId": "{6045F7F7-02B0-442A-96C7-A0CBCEFF7275}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Key": {
|
||||
"id": 1181151842701
|
||||
},
|
||||
"Value": {
|
||||
"ComponentData": {
|
||||
"{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": {
|
||||
"$type": "NodeSaveData"
|
||||
},
|
||||
"{328FF15C-C302-458F-A43D-E1794DE0904E}": {
|
||||
"$type": "GeneralNodeTitleComponentSaveData",
|
||||
"PaletteOverride": "StringNodeTitlePalette"
|
||||
},
|
||||
"{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": {
|
||||
"$type": "GeometrySaveData",
|
||||
"Position": [
|
||||
580.0,
|
||||
180.0
|
||||
]
|
||||
},
|
||||
"{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": {
|
||||
"$type": "StylingComponentSaveData"
|
||||
},
|
||||
"{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": {
|
||||
"$type": "PersistentIdComponentSaveData",
|
||||
"PersistentId": "{589F773E-D82A-4EDD-AEBD-3ADC07FC67CE}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Key": {
|
||||
"id": 5227099818161821361
|
||||
},
|
||||
"Value": {
|
||||
"ComponentData": {
|
||||
"{5F84B500-8C45-40D1-8EFC-A5306B241444}": {
|
||||
"$type": "SceneComponentSaveData"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"StatisticsHelper": {
|
||||
"InstanceCounter": [
|
||||
{
|
||||
"Key": 4199610336680704683,
|
||||
"Value": 1
|
||||
},
|
||||
{
|
||||
"Key": 10684225535275896474,
|
||||
"Value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
@@ -42,6 +42,16 @@
|
||||
"RayTracingAccelerationStructurePass"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "TerrainDetailTextureComputePass",
|
||||
"TemplateName": "TerrainDetailTextureComputePassTemplate",
|
||||
"Enabled": false
|
||||
},
|
||||
{
|
||||
"Name": "TerrainMacroTextureComputePass",
|
||||
"TemplateName": "TerrainMacroTextureComputePassTemplate",
|
||||
"Enabled": false
|
||||
},
|
||||
{
|
||||
"Name": "DepthPrePass",
|
||||
"TemplateName": "DepthMSAAParentTemplate",
|
||||
@@ -215,7 +225,7 @@
|
||||
// Note: The following two lines represent the choice of rendering pipeline for the hair.
|
||||
// You can either choose to use PPLL or ShortCut and accordingly change the flag
|
||||
// 'm_usePPLLRenderTechnique' in the class 'HairFeatureProcessor.cpp'
|
||||
// "TemplateName": "HairParentPassTemplate",
|
||||
// "TemplateName": "HairParentPassTemplate",
|
||||
"TemplateName": "HairParentShortCutPassTemplate",
|
||||
"Enabled": true,
|
||||
"Connections": [
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
"external_subdirectories": [
|
||||
"Gem"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+9
-47
@@ -44,51 +44,11 @@ include(cmake/SettingsRegistry.cmake)
|
||||
include(cmake/TestImpactFramework/LYTestImpactFramework.cmake)
|
||||
include(cmake/CMakeFiles.cmake)
|
||||
include(cmake/O3DEJson.cmake)
|
||||
include(cmake/Subdirectories.cmake)
|
||||
|
||||
################################################################################
|
||||
# Subdirectory processing
|
||||
################################################################################
|
||||
|
||||
# this function is building up the LY_EXTERNAL_SUBDIRS global property
|
||||
function(add_engine_gem_json_external_subdirectories gem_path)
|
||||
set(gem_json_path ${gem_path}/gem.json)
|
||||
if(EXISTS ${gem_json_path})
|
||||
read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json)
|
||||
foreach(gem_external_subdir ${gem_external_subdirs})
|
||||
file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path})
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
add_engine_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(add_engine_json_external_subdirectories)
|
||||
read_json_external_subdirs(engine_external_subdirs ${LY_ROOT_FOLDER}/engine.json)
|
||||
foreach(engine_external_subdir ${engine_external_subdirs})
|
||||
file(REAL_PATH ${engine_external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER})
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
add_engine_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(add_subdirectory_on_externalsubdirs)
|
||||
get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs})
|
||||
# Loop over the additional external subdirectories and invoke add_subdirectory on them
|
||||
foreach(external_directory ${LY_EXTERNAL_SUBDIRS})
|
||||
# Hash the external_directory name and append it to the Binary Directory section of add_subdirectory
|
||||
# This is to deal with potential situations where multiple external directories has the same last directory name
|
||||
# For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory
|
||||
file(REAL_PATH ${external_directory} full_directory_path)
|
||||
string(SHA256 full_directory_hash ${full_directory_path})
|
||||
# Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit
|
||||
# when the external subdirectory contains relative paths of significant length
|
||||
string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash)
|
||||
# Use the last directory as the suffix path to use for the Binary Directory
|
||||
get_filename_component(directory_name ${external_directory} NAME)
|
||||
add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash})
|
||||
endforeach()
|
||||
endfunction()
|
||||
# Gather the list of o3de_manifest external Subdirectories
|
||||
# into the LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST_PROPERTY
|
||||
add_o3de_manifest_json_external_subdirectories()
|
||||
|
||||
# Add the projects first so the Launcher can find them
|
||||
include(cmake/Projects.cmake)
|
||||
@@ -99,9 +59,11 @@ endif()
|
||||
|
||||
if(NOT INSTALLED_ENGINE)
|
||||
# Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra
|
||||
# external subdirectories. This should go before adding the rest of the targets so the targets are availbe to the launcher.
|
||||
# external subdirectories. This should go before adding the rest of the targets so the targets are available to the launcher.
|
||||
add_engine_json_external_subdirectories()
|
||||
add_subdirectory_on_externalsubdirs()
|
||||
|
||||
# Invoke add_subdirectory on external subdirectories that should be used a this point
|
||||
add_subdirectory_on_external_subdirs()
|
||||
|
||||
# Add the rest of the targets
|
||||
add_subdirectory(Assets)
|
||||
@@ -114,7 +76,7 @@ if(NOT INSTALLED_ENGINE)
|
||||
|
||||
else()
|
||||
ly_find_o3de_packages()
|
||||
add_subdirectory_on_externalsubdirs()
|
||||
add_subdirectory_on_external_subdirs()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include "AzAssetBrowserWindow.h"
|
||||
#include "AzAssetBrowser/ui_AssetBrowserWindow.h"
|
||||
|
||||
#include <AzToolsFramework/AssetBrowser/UI/AssetTreeView.h>
|
||||
#include <AzToolsFramework/AssetBrowser/UI/SortFilterProxyModel.hxx>
|
||||
#include <AzToolsFramework/AssetBrowser/UI/AssetBrowserModel.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetCache/AssetCacheBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserRequestBus.h>
|
||||
|
||||
const char* ASSET_BROWSER_PREVIEW_NAME = "Asset Browser (PREVIEW)";
|
||||
|
||||
AzAssetBrowserWindow::AzAssetBrowserWindow(const QString& name, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::AssetBrowserWindowClass())
|
||||
, m_assetDatabaseSortFilterProxyModel(new AssetBrowser::UI::SortFilterProxyModel(parent))
|
||||
, m_name(name)
|
||||
, m_assetBrowser(new AssetBrowser::UI::AssetTreeView(name, this))
|
||||
{
|
||||
EBUS_EVENT_RESULT(m_assetBrowserModel, AssetBrowser::AssetCache::AssetCacheRequestsBus, GetAssetBrowserModel);
|
||||
AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model");
|
||||
m_assetDatabaseSortFilterProxyModel->setSourceModel(m_assetBrowserModel);
|
||||
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->searchCriteriaWidget,
|
||||
&AzToolsFramework::SearchCriteriaWidget::SearchCriteriaChanged,
|
||||
m_assetDatabaseSortFilterProxyModel.data(),
|
||||
&AssetBrowser::UI::SortFilterProxyModel::OnSearchCriteriaChanged);
|
||||
|
||||
connect(m_assetBrowser, &QTreeView::customContextMenuRequested, this, &AzAssetBrowserWindow::OnContextMenu);
|
||||
}
|
||||
|
||||
AzAssetBrowserWindow::~AzAssetBrowserWindow()
|
||||
{
|
||||
m_assetBrowser->SaveState();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const AZ::Uuid& AzAssetBrowserWindow::GetClassID()
|
||||
{
|
||||
return AZ::AzTypeInfo<AzAssetBrowserWindow>::Uuid();
|
||||
}
|
||||
|
||||
void AzAssetBrowserWindow::OnContextMenu(const QPoint& point)
|
||||
{
|
||||
(void)point;
|
||||
//get the selected entries
|
||||
QModelIndexList sourceIndexes;
|
||||
for (const auto& index : m_assetBrowser->selectedIndexes())
|
||||
{
|
||||
sourceIndexes.push_back(m_assetDatabaseSortFilterProxyModel->mapToSource(index));
|
||||
}
|
||||
AZStd::vector<AssetBrowser::UI::Entry*> entries;
|
||||
m_assetBrowserModel->SourceIndexesToAssetDatabaseEntries(sourceIndexes, entries);
|
||||
|
||||
if (entries.empty() || entries.size() > 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto entry = entries.front();
|
||||
|
||||
EBUS_EVENT(AssetBrowser::AssetBrowserRequestBus::Bus, OnItemContextMenu, this, entry);
|
||||
}
|
||||
|
||||
#include <AzAssetBrowser/moc_AzAssetBrowserWindow.cpp>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AssetBrowserWindowClass;
|
||||
}
|
||||
|
||||
namespace AssetBrowser
|
||||
{
|
||||
namespace UI
|
||||
{
|
||||
class AssetTreeView;
|
||||
class SortFilterProxyModel;
|
||||
class AssetBrowserModel;
|
||||
}
|
||||
}
|
||||
|
||||
class AzAssetBrowserWindow
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AzAssetBrowserWindow, AZ::SystemAllocator, 0);
|
||||
AZ_TYPE_INFO(AzAssetBrowserWindow, "{20238D23-2670-44BC-9110-A51374C18B5A}");
|
||||
|
||||
explicit AzAssetBrowserWindow(const QString& name = "default", QWidget* parent = nullptr);
|
||||
virtual ~AzAssetBrowserWindow();
|
||||
|
||||
static const AZ::Uuid& GetClassID();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void OnContextMenu(const QPoint& point);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::AssetBrowserWindowClass> m_ui;
|
||||
QScopedPointer<AssetBrowser::UI::AssetBrowserModel> m_assetDatabaseModel;
|
||||
QScopedPointer<AssetBrowser::UI::SortFilterProxyModel> m_assetDatabaseSortFilterProxyModel;
|
||||
QString m_name;
|
||||
AssetBrowser::UI::AssetTreeView* m_assetBrowser;
|
||||
AssetBrowser::UI::AssetBrowserModel* m_assetBrowserModel;
|
||||
};
|
||||
|
||||
extern const char* ASSET_BROWSER_PREVIEW_NAME;
|
||||
@@ -78,10 +78,7 @@
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string extracomment="Collapse All"/>
|
||||
</property>
|
||||
<property name="toolTipDuration">
|
||||
<number>3</number>
|
||||
<string extracomment="Collapse All">Collapse All</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "CVarMenu.h"
|
||||
|
||||
CVarMenu::CVarMenu(QWidget* parent)
|
||||
: QMenu(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void CVarMenu::AddCVarToggleItem(CVarToggle cVarToggle)
|
||||
{
|
||||
// Add CVar toggle action
|
||||
QAction* action = addAction(cVarToggle.m_displayName);
|
||||
connect(action, &QAction::triggered, [this, cVarToggle](bool checked)
|
||||
{
|
||||
// Update the CVar's value based on the action's new checked state
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data());
|
||||
if (cVar)
|
||||
{
|
||||
SetCVar(cVar, checked ? cVarToggle.m_onValue : cVarToggle.m_offValue);
|
||||
}
|
||||
});
|
||||
action->setCheckable(true);
|
||||
|
||||
// Initialize the action's checked state based on the associated CVar's value
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data());
|
||||
bool checked = (cVar && cVar->GetFVal() == cVarToggle.m_onValue);
|
||||
action->setChecked(checked);
|
||||
}
|
||||
|
||||
void CVarMenu::AddCVarValuesItem(QString cVarName,
|
||||
QString displayName,
|
||||
CVarDisplayNameValuePairs availableCVarValues,
|
||||
float offValue)
|
||||
{
|
||||
// Add a submenu offering multiple values for one CVar
|
||||
QMenu* menu = addMenu(displayName);
|
||||
QActionGroup* group = new QActionGroup(menu);
|
||||
group->setExclusive(true);
|
||||
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(cVarName.toUtf8().data());
|
||||
float cVarValue = cVar ? cVar->GetFVal() : 0.0f;
|
||||
for (const auto& availableCVarValue : availableCVarValues)
|
||||
{
|
||||
QAction* action = menu->addAction(availableCVarValue.first);
|
||||
action->setCheckable(true);
|
||||
group->addAction(action);
|
||||
|
||||
float availableOnValue = availableCVarValue.second;
|
||||
connect(action, &QAction::triggered, [this, action, cVarName, availableOnValue, offValue](bool checked)
|
||||
{
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(cVarName.toUtf8().data());
|
||||
if (cVar)
|
||||
{
|
||||
if (!checked)
|
||||
{
|
||||
SetCVar(cVar, offValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Toggle the CVar and update the action's checked state to
|
||||
// allow none of the items to be checked in the exclusive group.
|
||||
// Otherwise we could have just used the action's currently checked
|
||||
// state and updated the CVar's value only
|
||||
bool cVarOn = (cVar->GetFVal() == availableOnValue);
|
||||
checked = !cVarOn;
|
||||
SetCVar(cVar, checked ? availableOnValue : offValue);
|
||||
action->setChecked(checked);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the action's checked state based on the CVar's current value
|
||||
bool checked = (cVarValue == availableOnValue);
|
||||
action->setChecked(checked);
|
||||
}
|
||||
}
|
||||
|
||||
void CVarMenu::AddUniqueCVarsItem(QString displayName,
|
||||
AZStd::vector<CVarToggle> availableCVars)
|
||||
{
|
||||
// Add a submenu of actions offering values for unique CVars
|
||||
QMenu* menu = addMenu(displayName);
|
||||
QActionGroup* group = new QActionGroup(menu);
|
||||
group->setExclusive(true);
|
||||
|
||||
for (const CVarToggle& availableCVar : availableCVars)
|
||||
{
|
||||
QAction* action = menu->addAction(availableCVar.m_displayName);
|
||||
action->setCheckable(true);
|
||||
group->addAction(action);
|
||||
|
||||
connect(action, &QAction::triggered, [this, action, availableCVar, availableCVars](bool checked)
|
||||
{
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(availableCVar.m_cVarName.toUtf8().data());
|
||||
if (cVar)
|
||||
{
|
||||
if (!checked)
|
||||
{
|
||||
SetCVar(cVar, availableCVar.m_offValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Toggle the CVar and update the action's checked state to
|
||||
// allow none of the items to be checked in the exclusive group.
|
||||
// Otherwise we could have just used the action's currently checked
|
||||
// state and updated the CVar's value only
|
||||
bool cVarOn = (cVar->GetFVal() == availableCVar.m_onValue);
|
||||
bool cVarChecked = !cVarOn;
|
||||
SetCVar(cVar, cVarChecked ? availableCVar.m_onValue : availableCVar.m_offValue);
|
||||
action->setChecked(cVarChecked);
|
||||
if (cVarChecked)
|
||||
{
|
||||
// Set the rest of the CVars in the group to their off values
|
||||
SetCVarsToOffValue(availableCVars, availableCVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the action's checked state based on its associated CVar's current value
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(availableCVar.m_cVarName.toUtf8().data());
|
||||
bool cVarChecked = (cVar && cVar->GetFVal() == availableCVar.m_onValue);
|
||||
action->setChecked(cVarChecked);
|
||||
if (cVarChecked)
|
||||
{
|
||||
// Set the rest of the CVars in the group to their off values
|
||||
SetCVarsToOffValue(availableCVars, availableCVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVarMenu::AddResetCVarsItem()
|
||||
{
|
||||
QAction* action = addAction(tr("Reset to Default"));
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
for (auto it : m_originalCVarValues)
|
||||
{
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(it.first.c_str());
|
||||
if (cVar)
|
||||
{
|
||||
cVar->Set(it.second);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CVarMenu::SetCVarsToOffValue(const AZStd::vector<CVarToggle>& cVarToggles, const CVarToggle& excludeCVarToggle)
|
||||
{
|
||||
// Set all but the specified CVars to their off values
|
||||
for (const CVarToggle& cVarToggle : cVarToggles)
|
||||
{
|
||||
if (cVarToggle.m_cVarName != excludeCVarToggle.m_cVarName
|
||||
|| cVarToggle.m_onValue != excludeCVarToggle.m_onValue)
|
||||
{
|
||||
ICVar* cVar = gEnv->pConsole->GetCVar(cVarToggle.m_cVarName.toUtf8().data());
|
||||
if (cVar)
|
||||
{
|
||||
SetCVar(cVar, cVarToggle.m_offValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVarMenu::SetCVar(ICVar* cVar, float newValue)
|
||||
{
|
||||
float oldValue = cVar->GetFVal();
|
||||
cVar->Set(newValue);
|
||||
|
||||
// Store original value for CVar if not already in the list
|
||||
m_originalCVarValues.emplace(AZStd::string(cVar->GetName()), oldValue);
|
||||
}
|
||||
|
||||
void CVarMenu::AddSeparator()
|
||||
{
|
||||
addSeparator();
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QMenu>
|
||||
#include <QString>
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
struct ICVar;
|
||||
|
||||
class CVarMenu
|
||||
: public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// CVar that can be toggled on and off
|
||||
struct CVarToggle
|
||||
{
|
||||
QString m_cVarName;
|
||||
QString m_displayName;
|
||||
float m_onValue;
|
||||
float m_offValue;
|
||||
};
|
||||
|
||||
// List of a CVar's available values and their descriptions
|
||||
using CVarDisplayNameValuePairs = AZStd::vector<AZStd::pair<QString, float>>;
|
||||
|
||||
CVarMenu(QWidget* parent = nullptr);
|
||||
|
||||
// Add an action that turns a CVar on/off
|
||||
void AddCVarToggleItem(CVarToggle cVarToggle);
|
||||
|
||||
// Add a submenu of actions for a CVar that offers multiple values for exclusive selection
|
||||
void AddCVarValuesItem(QString cVarName,
|
||||
QString displayName,
|
||||
CVarDisplayNameValuePairs availableCVarValues,
|
||||
float offValue);
|
||||
|
||||
// Add a submenu of actions for exclusively turning unique CVars on/off
|
||||
void AddUniqueCVarsItem(QString displayName,
|
||||
AZStd::vector<CVarToggle> availableCVars);
|
||||
|
||||
// Add an action to reset all CVars to their original values before they
|
||||
// were modified by this menu
|
||||
void AddResetCVarsItem();
|
||||
|
||||
void AddSeparator();
|
||||
|
||||
private:
|
||||
void SetCVarsToOffValue(const AZStd::vector<CVarToggle>& cVarToggles, const CVarToggle& excludeCVarToggle);
|
||||
void SetCVar(ICVar* cVar, float newValue);
|
||||
|
||||
// Original CVar values before they were modified by this menu
|
||||
AZStd::unordered_map<AZStd::string, float> m_originalCVarValues;
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
class CommandManagerRequests : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
|
||||
struct CommandDetails
|
||||
{
|
||||
AZStd::string m_name;
|
||||
AZStd::vector<AZStd::string> m_arguments;
|
||||
};
|
||||
|
||||
virtual AZStd::vector<AZStd::string> GetCommands() const = 0;
|
||||
virtual void ExecuteCommand(const AZStd::string& commandLine) {}
|
||||
|
||||
virtual void GetCommandDetails(AZStd::string commandName, CommandDetails& outArguments) const = 0;
|
||||
|
||||
};
|
||||
|
||||
using CommandManagerRequestBus = AZ::EBus<CommandManagerRequests>;
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "ConfigGroup.h"
|
||||
|
||||
namespace Config
|
||||
{
|
||||
CConfigGroup::CConfigGroup()
|
||||
{
|
||||
}
|
||||
|
||||
CConfigGroup::~CConfigGroup()
|
||||
{
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
delete var;
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigGroup::AddVar(IConfigVar* var)
|
||||
{
|
||||
m_vars.push_back(var);
|
||||
}
|
||||
|
||||
AZ::u32 CConfigGroup::GetVarCount()
|
||||
{
|
||||
return aznumeric_cast<AZ::u32>(m_vars.size());
|
||||
}
|
||||
|
||||
IConfigVar* CConfigGroup::GetVar(const char* szName)
|
||||
{
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
if (0 == _stricmp(szName, var->GetName().c_str()))
|
||||
{
|
||||
return var;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const IConfigVar* CConfigGroup::GetVar(const char* szName) const
|
||||
{
|
||||
for (const IConfigVar* var : m_vars)
|
||||
{
|
||||
if (0 == _stricmp(szName, var->GetName().c_str()))
|
||||
{
|
||||
return var;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IConfigVar* CConfigGroup::GetVar(AZ::u32 index)
|
||||
{
|
||||
if (index < m_vars.size())
|
||||
{
|
||||
return m_vars[index];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const IConfigVar* CConfigGroup::GetVar(AZ::u32 index) const
|
||||
{
|
||||
if (index < m_vars.size())
|
||||
{
|
||||
return m_vars[index];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CConfigGroup::SaveToXML(XmlNodeRef node)
|
||||
{
|
||||
// save only values that don't have default values
|
||||
for (const IConfigVar* var : m_vars)
|
||||
{
|
||||
if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave) || var->IsDefault())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* szName = var->GetName().c_str();
|
||||
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->Get(¤tValue);
|
||||
node->setAttr(szName, currentValue.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigGroup::LoadFromXML(XmlNodeRef node)
|
||||
{
|
||||
// load values that are save-able
|
||||
for (IConfigVar* var : m_vars)
|
||||
{
|
||||
if (var->IsFlagSet(IConfigVar::eFlag_DoNotSave))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const char* szName = var->GetName().c_str();
|
||||
|
||||
switch (var->GetType())
|
||||
{
|
||||
case IConfigVar::eType_BOOL:
|
||||
{
|
||||
bool currentValue = false;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_INT:
|
||||
{
|
||||
int currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_FLOAT:
|
||||
{
|
||||
float currentValue = 0;
|
||||
var->GetDefault(¤tValue);
|
||||
if (node->getAttr(szName, currentValue))
|
||||
{
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IConfigVar::eType_STRING:
|
||||
{
|
||||
AZStd::string currentValue;
|
||||
var->GetDefault(¤tValue);
|
||||
QString readValue(currentValue.c_str());
|
||||
if (node->getAttr(szName, readValue))
|
||||
{
|
||||
currentValue = readValue.toUtf8().data();
|
||||
var->Set(¤tValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
struct ICVar;
|
||||
class XmlNodeRef;
|
||||
|
||||
namespace Config
|
||||
{
|
||||
// Abstract configurable variable
|
||||
struct IConfigVar
|
||||
{
|
||||
public:
|
||||
enum EType
|
||||
{
|
||||
eType_BOOL,
|
||||
eType_INT,
|
||||
eType_FLOAT,
|
||||
eType_STRING,
|
||||
};
|
||||
|
||||
enum EFlags
|
||||
{
|
||||
eFlag_NoUI = 1 << 0,
|
||||
eFlag_NoCVar = 1 << 1,
|
||||
eFlag_DoNotSave = 1 << 2,
|
||||
};
|
||||
|
||||
IConfigVar(const char* szName, const char* szDescription, EType varType, AZ::u8 flags)
|
||||
: m_name(szName)
|
||||
, m_description(szDescription)
|
||||
, m_type(varType)
|
||||
, m_flags(flags)
|
||||
, m_ptr(nullptr)
|
||||
{};
|
||||
|
||||
virtual ~IConfigVar() = default;
|
||||
|
||||
AZ_FORCE_INLINE EType GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE const AZStd::string& GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE const AZStd::string& GetDescription() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE bool IsFlagSet(EFlags flag) const
|
||||
{
|
||||
return 0 != (m_flags & flag);
|
||||
}
|
||||
|
||||
virtual void Get(void* outPtr) const = 0;
|
||||
virtual void Set(const void* ptr) = 0;
|
||||
virtual bool IsDefault() const = 0;
|
||||
virtual void GetDefault(void* outPtr) const = 0;
|
||||
virtual void Reset() = 0;
|
||||
|
||||
static constexpr EType TranslateType(const bool&) { return eType_BOOL; }
|
||||
static constexpr EType TranslateType(const int&) { return eType_INT; }
|
||||
static constexpr EType TranslateType(const float&) { return eType_FLOAT; }
|
||||
static constexpr EType TranslateType(const AZStd::string&) { return eType_STRING; }
|
||||
|
||||
protected:
|
||||
EType m_type;
|
||||
AZ::u8 m_flags;
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_description;
|
||||
void* m_ptr;
|
||||
ICVar* m_pCVar;
|
||||
};
|
||||
|
||||
// Group of configuration variables with optional mapping to CVars
|
||||
class CConfigGroup
|
||||
{
|
||||
private:
|
||||
using TConfigVariables = AZStd::vector<IConfigVar*> ;
|
||||
TConfigVariables m_vars;
|
||||
|
||||
using TConsoleVariables = AZStd::vector<ICVar*>;
|
||||
TConsoleVariables m_consoleVars;
|
||||
|
||||
public:
|
||||
CConfigGroup();
|
||||
virtual ~CConfigGroup();
|
||||
|
||||
void AddVar(IConfigVar* var);
|
||||
AZ::u32 GetVarCount();
|
||||
IConfigVar* GetVar(const char* szName);
|
||||
IConfigVar* GetVar(AZ::u32 index);
|
||||
const IConfigVar* GetVar(const char* szName) const;
|
||||
const IConfigVar* GetVar(AZ::u32 index) const;
|
||||
|
||||
void SaveToXML(XmlNodeRef node);
|
||||
void LoadFromXML(XmlNodeRef node);
|
||||
};
|
||||
};
|
||||
@@ -1,369 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Tooltip that displays bitmap.
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "BitmapToolTip.h"
|
||||
|
||||
// Qt
|
||||
#include <QVBoxLayout>
|
||||
|
||||
// Editor
|
||||
#include "Util/Image.h"
|
||||
#include "Util/ImageUtil.h"
|
||||
|
||||
|
||||
static const int STATIC_TEXT_C_HEIGHT = 42;
|
||||
static const int HISTOGRAM_C_HEIGHT = 130;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CBitmapToolTip
|
||||
CBitmapToolTip::CBitmapToolTip(QWidget* parent)
|
||||
: QWidget(parent, Qt::ToolTip)
|
||||
, m_staticBitmap(new QLabel(this))
|
||||
, m_staticText(new QLabel(this))
|
||||
, m_rgbaHistogram(new CImageHistogramCtrl(this))
|
||||
, m_alphaChannelHistogram(new CImageHistogramCtrl(this))
|
||||
{
|
||||
m_nTimer = 0;
|
||||
m_hToolWnd = nullptr;
|
||||
m_bShowHistogram = true;
|
||||
m_bShowFullsize = false;
|
||||
m_eShowMode = ESHOW_RGB;
|
||||
|
||||
connect(&m_timer, &QTimer::timeout, this, &CBitmapToolTip::OnTimer);
|
||||
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
layout->addWidget(m_staticBitmap);
|
||||
layout->addWidget(m_staticText);
|
||||
|
||||
auto* histogramLayout = new QHBoxLayout();
|
||||
histogramLayout->addWidget(m_rgbaHistogram);
|
||||
histogramLayout->addWidget(m_alphaChannelHistogram);
|
||||
m_alphaChannelHistogram->setVisible(false);
|
||||
|
||||
layout->addLayout(histogramLayout);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
CBitmapToolTip::~CBitmapToolTip()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBitmapToolTip::GetShowMode(EShowMode& eShowMode, bool& bShowInOriginalSize) const
|
||||
{
|
||||
bShowInOriginalSize = CheckVirtualKey(Qt::Key_Space);
|
||||
eShowMode = ESHOW_RGB;
|
||||
|
||||
if (m_bHasAlpha)
|
||||
{
|
||||
if (CheckVirtualKey(Qt::Key_Control))
|
||||
{
|
||||
eShowMode = ESHOW_RGB_ALPHA;
|
||||
}
|
||||
else if (CheckVirtualKey(Qt::Key_Alt))
|
||||
{
|
||||
eShowMode = ESHOW_ALPHA;
|
||||
}
|
||||
else if (CheckVirtualKey(Qt::Key_Shift))
|
||||
{
|
||||
eShowMode = ESHOW_RGBA;
|
||||
}
|
||||
}
|
||||
else if (m_bIsLimitedHDR)
|
||||
{
|
||||
if (CheckVirtualKey(Qt::Key_Shift))
|
||||
{
|
||||
eShowMode = ESHOW_RGBE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* CBitmapToolTip::GetShowModeDescription(EShowMode eShowMode, [[maybe_unused]] bool bShowInOriginalSize) const
|
||||
{
|
||||
switch (eShowMode)
|
||||
{
|
||||
case ESHOW_RGB:
|
||||
return "RGB";
|
||||
case ESHOW_RGB_ALPHA:
|
||||
return "RGB+A";
|
||||
case ESHOW_ALPHA:
|
||||
return "Alpha";
|
||||
case ESHOW_RGBA:
|
||||
return "RGBA";
|
||||
case ESHOW_RGBE:
|
||||
return "RGBExp";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void CBitmapToolTip::RefreshViewmode()
|
||||
{
|
||||
LoadImage(m_filename);
|
||||
|
||||
if (m_eShowMode == ESHOW_RGB_ALPHA || m_eShowMode == ESHOW_RGBA)
|
||||
{
|
||||
m_rgbaHistogram->setVisible(true);
|
||||
m_alphaChannelHistogram->setVisible(true);
|
||||
}
|
||||
else if (m_eShowMode == ESHOW_ALPHA)
|
||||
{
|
||||
m_rgbaHistogram->setVisible(false);
|
||||
m_alphaChannelHistogram->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rgbaHistogram->setVisible(true);
|
||||
m_alphaChannelHistogram->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool CBitmapToolTip::LoadImage(const QString& imageFilename)
|
||||
{
|
||||
EShowMode eShowMode = ESHOW_RGB;
|
||||
const char* pShowModeDescription = "RGB";
|
||||
bool bShowInOriginalSize = false;
|
||||
|
||||
GetShowMode(eShowMode, bShowInOriginalSize);
|
||||
pShowModeDescription = GetShowModeDescription(eShowMode, bShowInOriginalSize);
|
||||
|
||||
QString convertedFileName = Path::GamePathToFullPath(Path::ReplaceExtension(imageFilename, ".dds"));
|
||||
|
||||
// We need to check against both the image filename and the converted filename as it is possible that the
|
||||
// converted file existed but failed to load previously and we reverted to loading the source asset.
|
||||
bool alreadyLoadedImage = ((m_filename == convertedFileName) || (m_filename == imageFilename));
|
||||
if (alreadyLoadedImage && (m_eShowMode == eShowMode) && (m_bShowFullsize == bShowInOriginalSize))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
CCryFile fileCheck;
|
||||
if (!fileCheck.Open(convertedFileName.toUtf8().data(), "rb"))
|
||||
{
|
||||
// if we didn't find it, then default back to just using what we can find (if any)
|
||||
convertedFileName = imageFilename;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileCheck.Close();
|
||||
}
|
||||
|
||||
m_eShowMode = eShowMode;
|
||||
m_bShowFullsize = bShowInOriginalSize;
|
||||
|
||||
CImageEx image;
|
||||
image.SetHistogramEqualization(CheckVirtualKey(Qt::Key_Shift));
|
||||
bool loadedRequestedAsset = true;
|
||||
if (!CImageUtil::LoadImage(convertedFileName, image))
|
||||
{
|
||||
//Failed to load the requested asset, let's try loading the source asset if available.
|
||||
loadedRequestedAsset = false;
|
||||
if (!CImageUtil::LoadImage(imageFilename, image))
|
||||
{
|
||||
m_staticBitmap->clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString imginfo;
|
||||
|
||||
m_filename = loadedRequestedAsset ? convertedFileName : imageFilename;
|
||||
m_bHasAlpha = image.HasAlphaChannel();
|
||||
m_bIsLimitedHDR = image.IsLimitedHDR();
|
||||
|
||||
GetShowMode(eShowMode, bShowInOriginalSize);
|
||||
pShowModeDescription = GetShowModeDescription(eShowMode, bShowInOriginalSize);
|
||||
|
||||
if (m_bHasAlpha)
|
||||
{
|
||||
imginfo = tr("%1x%2 %3\nShowing %4 (ALT=Alpha, SHIFT=RGBA, CTRL=RGB+A, SPACE=see in original size)");
|
||||
}
|
||||
else if (m_bIsLimitedHDR)
|
||||
{
|
||||
imginfo = tr("%1x%2 %3\nShowing %4 (SHIFT=see hist.-equalized, SPACE=see in original size)");
|
||||
}
|
||||
else
|
||||
{
|
||||
imginfo = tr("%1x%2 %3\nShowing %4 (SPACE=see in original size)");
|
||||
}
|
||||
|
||||
imginfo = imginfo.arg(image.GetWidth()).arg(image.GetHeight()).arg(image.GetFormatDescription()).arg(pShowModeDescription);
|
||||
|
||||
m_staticText->setText(imginfo);
|
||||
|
||||
int w = image.GetWidth();
|
||||
int h = image.GetHeight();
|
||||
int multiplier = (m_eShowMode == ESHOW_RGB_ALPHA ? 2 : 1);
|
||||
int originalW = w * multiplier;
|
||||
int originalH = h;
|
||||
|
||||
if (!bShowInOriginalSize || (w == 0))
|
||||
{
|
||||
w = 256;
|
||||
}
|
||||
if (!bShowInOriginalSize || (h == 0))
|
||||
{
|
||||
h = 256;
|
||||
}
|
||||
|
||||
w *= multiplier;
|
||||
|
||||
resize(w + 4, h + 4 + STATIC_TEXT_C_HEIGHT + HISTOGRAM_C_HEIGHT);
|
||||
setVisible(true);
|
||||
|
||||
CImageEx scaledImage;
|
||||
|
||||
if (bShowInOriginalSize && (originalW < w))
|
||||
{
|
||||
w = originalW;
|
||||
}
|
||||
if (bShowInOriginalSize && (originalH < h))
|
||||
{
|
||||
h = originalH;
|
||||
}
|
||||
|
||||
scaledImage.Allocate(w, h);
|
||||
|
||||
if (m_eShowMode == ESHOW_RGB_ALPHA)
|
||||
{
|
||||
CImageUtil::ScaleToDoubleFit(image, scaledImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
CImageUtil::ScaleToFit(image, scaledImage);
|
||||
}
|
||||
|
||||
if (m_eShowMode == ESHOW_RGB || m_eShowMode == ESHOW_RGBE)
|
||||
{
|
||||
scaledImage.SwapRedAndBlue();
|
||||
scaledImage.FillAlpha();
|
||||
}
|
||||
else if (m_eShowMode == ESHOW_ALPHA)
|
||||
{
|
||||
for (int hh = 0; hh < scaledImage.GetHeight(); hh++)
|
||||
{
|
||||
for (int ww = 0; ww < scaledImage.GetWidth(); ww++)
|
||||
{
|
||||
int a = scaledImage.ValueAt(ww, hh) >> 24;
|
||||
scaledImage.ValueAt(ww, hh) = RGB(a, a, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_eShowMode == ESHOW_RGB_ALPHA)
|
||||
{
|
||||
int halfWidth = scaledImage.GetWidth() / 2;
|
||||
for (int hh = 0; hh < scaledImage.GetHeight(); hh++)
|
||||
{
|
||||
for (int ww = 0; ww < halfWidth; ww++)
|
||||
{
|
||||
int r = GetRValue(scaledImage.ValueAt(ww, hh));
|
||||
int g = GetGValue(scaledImage.ValueAt(ww, hh));
|
||||
int b = GetBValue(scaledImage.ValueAt(ww, hh));
|
||||
int a = scaledImage.ValueAt(ww, hh) >> 24;
|
||||
scaledImage.ValueAt(ww, hh) = RGB(b, g, r);
|
||||
scaledImage.ValueAt(ww + halfWidth, hh) = RGB(a, a, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
else //if (m_showMode == ESHOW_RGBA)
|
||||
{
|
||||
scaledImage.SwapRedAndBlue();
|
||||
}
|
||||
|
||||
QImage qImage(scaledImage.GetWidth(), scaledImage.GetHeight(), QImage::Format_RGB32);
|
||||
memcpy(qImage.bits(), scaledImage.GetData(), qImage.sizeInBytes());
|
||||
m_staticBitmap->setPixmap(QPixmap::fromImage(qImage));
|
||||
|
||||
if (m_bShowHistogram && scaledImage.GetData())
|
||||
{
|
||||
m_rgbaHistogram->ComputeHistogram(image, CImageHistogram::eImageFormat_32BPP_BGRA);
|
||||
m_rgbaHistogram->setDrawMode(EHistogramDrawMode::OverlappedRGB);
|
||||
|
||||
m_alphaChannelHistogram->histogramDisplay()->CopyComputedDataFrom(m_rgbaHistogram->histogramDisplay());
|
||||
m_alphaChannelHistogram->setDrawMode(EHistogramDrawMode::AlphaChannel);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBitmapToolTip::OnTimer()
|
||||
{
|
||||
/*
|
||||
if (IsWindowVisible())
|
||||
{
|
||||
if (m_bHaveAnythingToRender)
|
||||
Invalidate();
|
||||
}
|
||||
*/
|
||||
if (m_hToolWnd)
|
||||
{
|
||||
QRect toolRc(m_toolRect);
|
||||
QRect rc = geometry();
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
toolRc.moveTopLeft(m_hToolWnd->mapToGlobal(toolRc.topLeft()));
|
||||
if (!toolRc.contains(cursorPos) && !rc.contains(cursorPos))
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
RefreshViewmode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBitmapToolTip::showEvent([[maybe_unused]] QShowEvent* event)
|
||||
{
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
move(cursorPos);
|
||||
m_timer.start(500);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBitmapToolTip::hideEvent([[maybe_unused]] QHideEvent* event)
|
||||
{
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CBitmapToolTip::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Control || event->key() == Qt::Key_Alt || event->key() == Qt::Key_Shift)
|
||||
{
|
||||
RefreshViewmode();
|
||||
}
|
||||
}
|
||||
|
||||
void CBitmapToolTip::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Control || event->key() == Qt::Key_Alt || event->key() == Qt::Key_Shift)
|
||||
{
|
||||
RefreshViewmode();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CBitmapToolTip::SetTool(QWidget* pWnd, const QRect& rect)
|
||||
{
|
||||
assert(pWnd);
|
||||
m_hToolWnd = pWnd;
|
||||
m_toolRect = rect;
|
||||
}
|
||||
|
||||
#include <Controls/moc_BitmapToolTip.cpp>
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Tooltip that displays bitmap.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_CONTROLS_BITMAPTOOLTIP_H
|
||||
#define CRYINCLUDE_EDITOR_CONTROLS_BITMAPTOOLTIP_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "Controls/ImageHistogramCtrl.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CBitmapToolTip
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
// Construction
|
||||
public:
|
||||
|
||||
enum EShowMode
|
||||
{
|
||||
ESHOW_RGB = 0,
|
||||
ESHOW_ALPHA,
|
||||
ESHOW_RGBA,
|
||||
ESHOW_RGB_ALPHA,
|
||||
ESHOW_RGBE
|
||||
};
|
||||
|
||||
CBitmapToolTip(QWidget* parent = nullptr);
|
||||
virtual ~CBitmapToolTip();
|
||||
|
||||
bool Create(const RECT& rect);
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void RefreshViewmode();
|
||||
|
||||
bool LoadImage(const QString& imageFilename);
|
||||
void SetTool(QWidget* pWnd, const QRect& rect);
|
||||
|
||||
// Generated message map functions
|
||||
protected:
|
||||
void OnTimer();
|
||||
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
|
||||
void showEvent(QShowEvent* event) override;
|
||||
void hideEvent(QHideEvent* event) override;
|
||||
|
||||
private:
|
||||
void GetShowMode(EShowMode& showMode, bool& showInOriginalSize) const;
|
||||
const char* GetShowModeDescription(EShowMode showMode, bool showInOriginalSize) const;
|
||||
|
||||
QLabel* m_staticBitmap;
|
||||
QLabel* m_staticText;
|
||||
QString m_filename;
|
||||
bool m_bShowHistogram;
|
||||
EShowMode m_eShowMode;
|
||||
bool m_bShowFullsize;
|
||||
bool m_bHasAlpha;
|
||||
bool m_bIsLimitedHDR;
|
||||
CImageHistogramCtrl* m_rgbaHistogram;
|
||||
CImageHistogramCtrl* m_alphaChannelHistogram;
|
||||
int m_nTimer;
|
||||
QWidget* m_hToolWnd;
|
||||
QRect m_toolRect;
|
||||
QTimer m_timer;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_CONTROLS_BITMAPTOOLTIP_H
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "QBitmapPreviewDialog.h"
|
||||
#include <Controls/ui_QBitmapPreviewDialog.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QPainter>
|
||||
#include <QScreen>
|
||||
|
||||
void QBitmapPreviewDialog::ImageData::setRgba8888(const void* buffer, const int& w, const int& h)
|
||||
{
|
||||
const unsigned long bytes = w * h * 4;
|
||||
m_buffer.resize(bytes);
|
||||
memcpy(m_buffer.data(), buffer, bytes);
|
||||
m_image = QImage((uchar*)m_buffer.constData(), w, h, QImage::Format::Format_RGBA8888);
|
||||
}
|
||||
|
||||
static void fillChecker(int w, int h, unsigned int* dst)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
dst[y * w + x] = 0xFF000000 | (((x >> 2) + (y >> 2)) % 2 == 0 ? 0x007F7F7F : 0x00000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QBitmapPreviewDialog::QBitmapPreviewDialog(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::QBitmapTooltip)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setAttribute(Qt::WA_ShowWithoutActivating);
|
||||
|
||||
// Clear label text
|
||||
ui->m_placeholderBitmap->setText("");
|
||||
ui->m_placeholderHistogram->setText("");
|
||||
|
||||
ui->m_bitmapSize->setProperty("tableRow", "Odd");
|
||||
ui->m_Mips->setProperty("tableRow", "Even");
|
||||
ui->m_Mean->setProperty("tableRow", "Odd");
|
||||
ui->m_StdDev->setProperty("tableRow", "Even");
|
||||
ui->m_Median->setProperty("tableRow", "Odd");
|
||||
ui->m_labelForBitmapSize->setProperty("tooltipLabel", "content");
|
||||
ui->m_labelForMean->setProperty("tooltipLabel", "content");
|
||||
ui->m_labelForMedian->setProperty("tooltipLabel", "content");
|
||||
ui->m_labelForMips->setProperty("tooltipLabel", "content");
|
||||
ui->m_labelForStdDev->setProperty("tooltipLabel", "content");
|
||||
ui->m_vBitmapSize->setProperty("tooltipLabel", "content");
|
||||
ui->m_vMean->setProperty("tooltipLabel", "content");
|
||||
ui->m_vMedian->setProperty("tooltipLabel", "content");
|
||||
ui->m_vMips->setProperty("tooltipLabel", "content");
|
||||
ui->m_vStdDev->setProperty("tooltipLabel", "content");
|
||||
|
||||
// Initialize placeholder images
|
||||
const int w = 64;
|
||||
const int h = 64;
|
||||
QByteArray buffer;
|
||||
buffer.resize(w * h * 4);
|
||||
unsigned int* dst = (unsigned int*)buffer.data();
|
||||
fillChecker(w, h, dst);
|
||||
m_checker.setRgba8888(buffer.constData(), w, h);
|
||||
|
||||
m_initialSize = window()->window()->geometry().size();
|
||||
}
|
||||
|
||||
QBitmapPreviewDialog::~QBitmapPreviewDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::setImageRgba8888(const void* buffer, const int& w, const int& h, [[maybe_unused]] const QString& info)
|
||||
{
|
||||
m_imageMain.setRgba8888(buffer, w, h);
|
||||
}
|
||||
|
||||
|
||||
QRect QBitmapPreviewDialog::getHistogramArea()
|
||||
{
|
||||
return QRect(ui->m_placeholderHistogram->pos(), ui->m_placeholderHistogram->size());
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::setFullSize(const bool& fullSize)
|
||||
{
|
||||
if (fullSize)
|
||||
{
|
||||
QSize desktop = QApplication::screenAt(ui->m_placeholderBitmap->pos())->availableGeometry().size();
|
||||
QSize image = m_imageMain.m_image.size();
|
||||
QPoint location = mapToGlobal(ui->m_placeholderBitmap->pos());
|
||||
QSize finalSize;
|
||||
finalSize.setWidth((image.width() < (desktop.width() - location.x())) ? image.width() : (desktop.width() - location.x()));
|
||||
finalSize.setHeight((image.height() < (desktop.height() - location.y())) ? image.height() : (desktop.height() - location.y()));
|
||||
float scale = (finalSize.width() < finalSize.height()) ? finalSize.width() / float(m_imageMain.m_image.width()) : finalSize.height() / float(m_imageMain.m_image.height());
|
||||
ui->m_placeholderBitmap->setFixedSize(scale * m_imageMain.m_image.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->m_placeholderBitmap->setFixedSize(256, 256);
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::paintEvent(QPaintEvent* e)
|
||||
{
|
||||
QWidget::paintEvent(e);
|
||||
QRect rect(ui->m_placeholderBitmap->pos(), ui->m_placeholderBitmap->size());
|
||||
drawImageData(rect, m_imageMain);
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::drawImageData(const QRect& rect, const ImageData& imgData)
|
||||
{
|
||||
// Draw the
|
||||
QPainter p(this);
|
||||
p.drawImage(rect.topLeft(), m_checker.m_image.scaled(rect.size()));
|
||||
p.drawImage(rect.topLeft(), imgData.m_image.scaled(rect.size()));
|
||||
|
||||
// Draw border
|
||||
QPen pen;
|
||||
pen.setColor(QColor(0, 0, 0));
|
||||
p.drawRect(rect.top(), rect.left(), rect.width() - 1, rect.height());
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::setSize(QString _value)
|
||||
{
|
||||
ui->m_vBitmapSize->setText(_value);
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::setMips(QString _value)
|
||||
{
|
||||
ui->m_vMips->setText(_value);
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::setMean(QString _value)
|
||||
{
|
||||
ui->m_vMean->setText(_value);
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::setMedian(QString _value)
|
||||
{
|
||||
ui->m_vMedian->setText(_value);
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialog::setStdDev(QString _value)
|
||||
{
|
||||
ui->m_vStdDev->setText(_value);
|
||||
}
|
||||
|
||||
QSize QBitmapPreviewDialog::GetCurrentBitmapSize()
|
||||
{
|
||||
return ui->m_placeholderBitmap->size();
|
||||
}
|
||||
|
||||
QSize QBitmapPreviewDialog::GetOriginalImageSize()
|
||||
{
|
||||
return m_imageMain.m_image.size();
|
||||
}
|
||||
|
||||
|
||||
#include <Controls/moc_QBitmapPreviewDialog.cpp>
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef QBITMAPPREVIEWDIALOG_H
|
||||
#define QBITMAPPREVIEWDIALOG_H
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QWidget>
|
||||
#include <QPixmap>
|
||||
#include <QImage>
|
||||
#endif
|
||||
|
||||
class QLabel;
|
||||
|
||||
namespace Ui {
|
||||
class QBitmapTooltip;
|
||||
}
|
||||
|
||||
class QBitmapPreviewDialog
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
struct ImageData
|
||||
{
|
||||
QByteArray m_buffer;
|
||||
QImage m_image;
|
||||
|
||||
void setRgba8888(const void* buffer, const int& w, const int& h);
|
||||
};
|
||||
|
||||
public:
|
||||
explicit QBitmapPreviewDialog(QWidget* parent = 0);
|
||||
virtual ~QBitmapPreviewDialog();
|
||||
QSize GetCurrentBitmapSize();
|
||||
QSize GetOriginalImageSize();
|
||||
|
||||
protected:
|
||||
void setImageRgba8888(const void* buffer, const int& w, const int& h, const QString& info);
|
||||
void setSize(QString _value);
|
||||
void setMips(QString _value);
|
||||
void setMean(QString _value);
|
||||
void setMedian(QString _value);
|
||||
void setStdDev(QString _value);
|
||||
QRect getHistogramArea();
|
||||
void setFullSize(const bool& fullSize);
|
||||
|
||||
void paintEvent(QPaintEvent* e) override;
|
||||
|
||||
private:
|
||||
void drawImageData(const QRect& rect, const ImageData& imgData);
|
||||
|
||||
protected:
|
||||
Ui::QBitmapTooltip* ui;
|
||||
QSize m_initialSize;
|
||||
ImageData m_checker;
|
||||
ImageData m_imageMain;
|
||||
};
|
||||
|
||||
#endif // QBITMAPPREVIEWDIALOG_H
|
||||
@@ -1,390 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QBitmapTooltip</class>
|
||||
<widget class="QWidget" name="QBitmapTooltip">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>256</width>
|
||||
<height>510</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>256</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_placeholderBitmap">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>256</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bitmap Area</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_placeholderHistogram">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>128</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Histogram Area</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_bitmapSize" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_labelForBitmapSize">
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_vBitmapSize">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Size Value</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_Mips" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_labelForMips">
|
||||
<property name="text">
|
||||
<string>DXT5 Mips:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_vMips">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Size Value</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_Mean" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_labelForMean">
|
||||
<property name="text">
|
||||
<string>Mean:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_vMean">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Size Value</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_StdDev" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_labelForStdDev">
|
||||
<property name="text">
|
||||
<string>StdDev:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_vStdDev">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Size Value</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_Median" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_labelForMedian">
|
||||
<property name="text">
|
||||
<string>Median:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_vMedian">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Size Value</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,528 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "QBitmapPreviewDialogImp.h"
|
||||
|
||||
// Cry
|
||||
#include <ITexture.h>
|
||||
|
||||
// EditorCore
|
||||
#include <Util/Image.h>
|
||||
#include <Include/IImageUtil.h>
|
||||
|
||||
// QT
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: class '...' needs to have dll-interface to be used by clients of class '...'
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <qmath.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include <Controls/ui_QBitmapPreviewDialog.h>
|
||||
|
||||
static const int kDefaultWidth = 256;
|
||||
static const int kDefaultHeight = 256;
|
||||
|
||||
QBitmapPreviewDialogImp::QBitmapPreviewDialogImp(QWidget* parent)
|
||||
: QBitmapPreviewDialog(parent)
|
||||
, m_image(new CImageEx())
|
||||
, m_showOriginalSize(false)
|
||||
, m_showMode(ESHOW_RGB)
|
||||
, m_histrogramMode(eHistogramMode_OverlappedRGB)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setImage("");
|
||||
ui->m_placeholderBitmap->setStyleSheet("background-color: rgba(0, 0, 0, 0);");
|
||||
ui->m_placeholderHistogram->setStyleSheet("background-color: rgba(0, 0, 0, 0);");
|
||||
|
||||
ui->m_labelForBitmapSize->setProperty("tooltipLabel", "Content");
|
||||
ui->m_labelForMean->setProperty("tooltipLabel", "Content");
|
||||
ui->m_labelForMedian->setProperty("tooltipLabel", "Content");
|
||||
ui->m_labelForMips->setProperty("tooltipLabel", "Content");
|
||||
ui->m_labelForStdDev->setProperty("tooltipLabel", "Content");
|
||||
|
||||
ui->m_vBitmapSize->setProperty("tooltipLabel", "Content");
|
||||
ui->m_vMean->setProperty("tooltipLabel", "Content");
|
||||
ui->m_vMedian->setProperty("tooltipLabel", "Content");
|
||||
ui->m_vMips->setProperty("tooltipLabel", "Content");
|
||||
ui->m_vStdDev->setProperty("tooltipLabel", "Content");
|
||||
|
||||
setUIStyleMode(EUISTYLE_IMAGE_ONLY);
|
||||
}
|
||||
|
||||
QBitmapPreviewDialogImp::~QBitmapPreviewDialogImp()
|
||||
{
|
||||
SAFE_DELETE(m_image);
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::setImage(const QString path)
|
||||
{
|
||||
if (path.isEmpty()
|
||||
|| m_path == path
|
||||
|| !GetIEditor()->GetImageUtil()->LoadImage(path.toUtf8().data(), *m_image))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_showOriginalSize = isSizeSmallerThanDefault();
|
||||
m_path = path;
|
||||
refreshData();
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::setShowMode(EShowMode mode)
|
||||
{
|
||||
if (mode == ESHOW_NumModes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_showMode = mode;
|
||||
refreshData();
|
||||
update();
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::toggleShowMode()
|
||||
{
|
||||
m_showMode = (EShowMode)(((int)m_showMode + 1) % ESHOW_NumModes);
|
||||
refreshData();
|
||||
update();
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::setUIStyleMode(EUIStyle mode)
|
||||
{
|
||||
if (mode >= EUISTYLE_NumModes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_uiStyle = mode;
|
||||
if (m_uiStyle == EUISTYLE_IMAGE_ONLY)
|
||||
{
|
||||
ui->m_placeholderHistogram->hide();
|
||||
|
||||
ui->m_labelForBitmapSize->hide();
|
||||
ui->m_labelForMean->hide();
|
||||
ui->m_labelForMedian->hide();
|
||||
ui->m_labelForMips->hide();
|
||||
ui->m_labelForStdDev->hide();
|
||||
|
||||
ui->m_vBitmapSize->hide();
|
||||
ui->m_vMean->hide();
|
||||
ui->m_vMedian->hide();
|
||||
ui->m_vMips->hide();
|
||||
ui->m_vStdDev->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->m_placeholderHistogram->show();
|
||||
|
||||
ui->m_labelForBitmapSize->show();
|
||||
ui->m_labelForMean->show();
|
||||
ui->m_labelForMedian->show();
|
||||
ui->m_labelForMips->show();
|
||||
ui->m_labelForStdDev->show();
|
||||
|
||||
ui->m_vBitmapSize->show();
|
||||
ui->m_vMean->show();
|
||||
ui->m_vMedian->show();
|
||||
ui->m_vMips->show();
|
||||
ui->m_vStdDev->show();
|
||||
}
|
||||
}
|
||||
|
||||
const QBitmapPreviewDialogImp::EShowMode& QBitmapPreviewDialogImp::getShowMode() const
|
||||
{
|
||||
return m_showMode;
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::setHistogramMode(EHistogramMode mode)
|
||||
{
|
||||
if (mode == eHistogramMode_NumModes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_histrogramMode = mode;
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::toggleHistrogramMode()
|
||||
{
|
||||
m_histrogramMode = (EHistogramMode)(((int)m_histrogramMode + 1) % eHistogramMode_NumModes);
|
||||
update();
|
||||
}
|
||||
|
||||
const QBitmapPreviewDialogImp::EHistogramMode& QBitmapPreviewDialogImp::getHistogramMode() const
|
||||
{
|
||||
return m_histrogramMode;
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::toggleOriginalSize()
|
||||
{
|
||||
m_showOriginalSize = !m_showOriginalSize;
|
||||
|
||||
refreshData();
|
||||
update();
|
||||
}
|
||||
|
||||
bool QBitmapPreviewDialogImp::isSizeSmallerThanDefault()
|
||||
{
|
||||
return m_image->GetWidth() < kDefaultWidth && m_image->GetHeight() < kDefaultHeight;
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::setOriginalSize(bool value)
|
||||
{
|
||||
m_showOriginalSize = value;
|
||||
|
||||
refreshData();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
const char* QBitmapPreviewDialogImp::GetShowModeDescription(EShowMode eShowMode, [[maybe_unused]] bool bShowInOriginalSize) const
|
||||
{
|
||||
switch (eShowMode)
|
||||
{
|
||||
case ESHOW_RGB:
|
||||
return "RGB";
|
||||
case ESHOW_RGB_ALPHA:
|
||||
return "RGB+A";
|
||||
case ESHOW_ALPHA:
|
||||
return "Alpha";
|
||||
case ESHOW_RGBA:
|
||||
return "RGBA";
|
||||
case ESHOW_RGBE:
|
||||
return "RGBExp";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
const char* getHistrogramModeStr(QBitmapPreviewDialogImp::EHistogramMode mode, bool shortName)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case QBitmapPreviewDialogImp::eHistogramMode_Luminosity:
|
||||
return shortName ? "Lum" : "Luminosity";
|
||||
case QBitmapPreviewDialogImp::eHistogramMode_OverlappedRGB:
|
||||
return shortName ? "Overlap" : "Overlapped RGBA";
|
||||
case QBitmapPreviewDialogImp::eHistogramMode_SplitRGB:
|
||||
return shortName ? "R|G|B" : "Split RGB";
|
||||
case QBitmapPreviewDialogImp::eHistogramMode_RedChannel:
|
||||
return shortName ? "Red" : "Red Channel";
|
||||
case QBitmapPreviewDialogImp::eHistogramMode_GreenChannel:
|
||||
return shortName ? "Green" : "Green Channel";
|
||||
case QBitmapPreviewDialogImp::eHistogramMode_BlueChannel:
|
||||
return shortName ? "Blue" : "Blue Channel";
|
||||
case QBitmapPreviewDialogImp::eHistogramMode_AlphaChannel:
|
||||
return shortName ? "Alpha" : "Alpha Channel";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::refreshData()
|
||||
{
|
||||
// Check if we have some usefull data loaded
|
||||
if (m_image->GetWidth() * m_image->GetHeight() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int w = m_image->GetWidth();
|
||||
int h = m_image->GetHeight();
|
||||
|
||||
int multiplier = (m_showMode == ESHOW_RGB_ALPHA ? 2 : 1);
|
||||
int originalW = w * multiplier;
|
||||
int originalH = h;
|
||||
|
||||
if (!m_showOriginalSize || (w == 0))
|
||||
{
|
||||
w = kDefaultWidth;
|
||||
}
|
||||
if (!m_showOriginalSize || (h == 0))
|
||||
{
|
||||
h = kDefaultHeight;
|
||||
}
|
||||
|
||||
w *= multiplier;
|
||||
|
||||
CImageEx scaledImage;
|
||||
|
||||
if (m_showOriginalSize && (originalW < w))
|
||||
{
|
||||
w = originalW;
|
||||
}
|
||||
if (m_showOriginalSize && (originalH < h))
|
||||
{
|
||||
h = originalH;
|
||||
}
|
||||
|
||||
scaledImage.Allocate(w, h);
|
||||
|
||||
if (m_showMode == ESHOW_RGB_ALPHA)
|
||||
{
|
||||
GetIEditor()->GetImageUtil()->ScaleToDoubleFit(*m_image, scaledImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetIEditor()->GetImageUtil()->ScaleToFit(*m_image, scaledImage);
|
||||
}
|
||||
|
||||
if (m_showMode == ESHOW_RGB || m_showMode == ESHOW_RGBE)
|
||||
{
|
||||
scaledImage.FillAlpha();
|
||||
}
|
||||
else if (m_showMode == ESHOW_ALPHA)
|
||||
{
|
||||
for (int h2 = 0; h2 < scaledImage.GetHeight(); h2++)
|
||||
{
|
||||
for (int w2 = 0; w2 < scaledImage.GetWidth(); w2++)
|
||||
{
|
||||
int a = scaledImage.ValueAt(w2, h2) >> 24;
|
||||
scaledImage.ValueAt(w2, h2) = RGB(a, a, a) | (a << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_showMode == ESHOW_RGB_ALPHA)
|
||||
{
|
||||
int halfWidth = scaledImage.GetWidth() / 2;
|
||||
for (int h2 = 0; h2 < scaledImage.GetHeight(); h2++)
|
||||
{
|
||||
for (int w2 = 0; w2 < halfWidth; w2++)
|
||||
{
|
||||
int r = GetRValue(scaledImage.ValueAt(w2, h2));
|
||||
int g = GetGValue(scaledImage.ValueAt(w2, h2));
|
||||
int b = GetBValue(scaledImage.ValueAt(w2, h2));
|
||||
int a = scaledImage.ValueAt(w2, h2) >> 24;
|
||||
scaledImage.ValueAt(w2, h2) = RGB(r, g, b) | (a << 24);
|
||||
scaledImage.ValueAt(w2 + halfWidth, h2) = RGB(a, a, a) | (a << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setImageRgba8888(scaledImage.GetData(), w, h, "");
|
||||
setSize(QString().asprintf("%d x %d", m_image->GetWidth(), m_image->GetHeight()));
|
||||
setMips(QString().asprintf("%d", m_image->GetNumberOfMipMaps()));
|
||||
|
||||
setFullSize(m_showOriginalSize);
|
||||
|
||||
// Compute histogram
|
||||
m_histogram.ComputeHistogram((BYTE*)scaledImage.GetData(), w, h, CImageHistogram::eImageFormat_32BPP_RGBA);
|
||||
}
|
||||
|
||||
void QBitmapPreviewDialogImp::paintEvent(QPaintEvent* e)
|
||||
{
|
||||
QBitmapPreviewDialog::paintEvent(e);
|
||||
|
||||
//if showing original size hide other information so it's easier to see
|
||||
if (m_showOriginalSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_uiStyle == EUISTYLE_IMAGE_ONLY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QPainter p(this);
|
||||
QPen pen;
|
||||
QPainterPath path[4];
|
||||
|
||||
// Fill background color
|
||||
QRect histogramRect = getHistogramArea();
|
||||
p.fillRect(histogramRect, QColor(255, 255, 255));
|
||||
|
||||
// Draw borders
|
||||
pen.setColor(QColor(0, 0, 0));
|
||||
p.setPen(pen);
|
||||
p.drawRect(histogramRect);
|
||||
|
||||
// Draw histogram
|
||||
|
||||
QVector<int> drawChannels;
|
||||
|
||||
switch (m_histrogramMode)
|
||||
{
|
||||
case eHistogramMode_Luminosity:
|
||||
drawChannels.push_back(3);
|
||||
break;
|
||||
case eHistogramMode_SplitRGB:
|
||||
drawChannels.push_back(0);
|
||||
drawChannels.push_back(1);
|
||||
drawChannels.push_back(2);
|
||||
break;
|
||||
case eHistogramMode_OverlappedRGB:
|
||||
drawChannels.push_back(0);
|
||||
drawChannels.push_back(1);
|
||||
drawChannels.push_back(2);
|
||||
break;
|
||||
case eHistogramMode_RedChannel:
|
||||
drawChannels.push_back(0);
|
||||
break;
|
||||
case eHistogramMode_GreenChannel:
|
||||
drawChannels.push_back(1);
|
||||
break;
|
||||
case eHistogramMode_BlueChannel:
|
||||
drawChannels.push_back(2);
|
||||
break;
|
||||
case eHistogramMode_AlphaChannel:
|
||||
drawChannels.push_back(3);
|
||||
break;
|
||||
}
|
||||
|
||||
int graphWidth = qMax(histogramRect.width(), 1);
|
||||
int graphHeight = qMax(histogramRect.height() - 2, 0);
|
||||
int graphBottom = histogramRect.bottom() + 1;
|
||||
int currX[4] = {0, 0, 0, 0};
|
||||
int prevX[4] = {0, 0, 0, 0};
|
||||
float scale = 0.0f;
|
||||
static const int numSubGraphs = 3;
|
||||
const int subGraph = qCeil(graphWidth / numSubGraphs);
|
||||
|
||||
// Fill background for Split RGB histogram
|
||||
if (m_histrogramMode == eHistogramMode_SplitRGB)
|
||||
{
|
||||
const static QColor backgroundColor[numSubGraphs] =
|
||||
{
|
||||
QColor(255, 220, 220),
|
||||
QColor(220, 255, 220),
|
||||
QColor(220, 220, 255)
|
||||
};
|
||||
|
||||
for (int i = 0; i < numSubGraphs; i++)
|
||||
{
|
||||
p.fillRect(histogramRect.left() + subGraph * i,
|
||||
histogramRect.top(),
|
||||
subGraph + (i == numSubGraphs - 1 ? 1 : 0),
|
||||
histogramRect.height(), backgroundColor[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int lastHeight[CImageHistogram::kNumChannels] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX };
|
||||
|
||||
for (int x = 0; x < graphWidth; ++x)
|
||||
{
|
||||
for (int j = 0; j < drawChannels.size(); j++)
|
||||
{
|
||||
const int c = drawChannels[j];
|
||||
int& curr_x = currX[c];
|
||||
int& prev_x = prevX[c];
|
||||
int& last_height = lastHeight[c];
|
||||
QPainterPath& curr_path = path[c];
|
||||
|
||||
|
||||
curr_x = histogramRect.left() + x + 1;
|
||||
int i = static_cast<int>(((float)x / (graphWidth - 1)) * (CImageHistogram::kNumColorLevels - 1));
|
||||
if (m_histrogramMode == eHistogramMode_SplitRGB)
|
||||
{
|
||||
// Filter out to area which we are interested
|
||||
const int k = x / subGraph;
|
||||
if (k != c)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
i = qCeil((i - (subGraph * c)) * numSubGraphs);
|
||||
i = qMin(i, CImageHistogram::kNumColorLevels - 1);
|
||||
i = qMax(i, 0);
|
||||
}
|
||||
|
||||
if (m_histrogramMode == eHistogramMode_Luminosity)
|
||||
{
|
||||
scale = (float)m_histogram.m_lumCount[i] / m_histogram.m_maxLumCount;
|
||||
}
|
||||
else if (m_histogram.m_maxCount[c])
|
||||
{
|
||||
scale = (float)m_histogram.m_count[c][i] / m_histogram.m_maxCount[c];
|
||||
}
|
||||
|
||||
int height = static_cast<int>(graphBottom - graphHeight * scale);
|
||||
if (last_height == INT_MAX)
|
||||
{
|
||||
last_height = height;
|
||||
}
|
||||
|
||||
curr_path.moveTo(prev_x, last_height);
|
||||
curr_path.lineTo(curr_x, height);
|
||||
last_height = height;
|
||||
|
||||
if (prev_x == INT_MAX)
|
||||
{
|
||||
prev_x = curr_x;
|
||||
}
|
||||
|
||||
prev_x = curr_x;
|
||||
}
|
||||
}
|
||||
|
||||
static const QColor kChannelColor[4] =
|
||||
{
|
||||
QColor(255, 0, 0),
|
||||
QColor(0, 255, 0),
|
||||
QColor(0, 0, 255),
|
||||
QColor(120, 120, 120)
|
||||
};
|
||||
|
||||
for (int i = 0; i < drawChannels.size(); i++)
|
||||
{
|
||||
const int c = drawChannels[i];
|
||||
pen.setColor(kChannelColor[c]);
|
||||
p.setPen(pen);
|
||||
p.drawPath(path[c]);
|
||||
}
|
||||
|
||||
// Update histogram info
|
||||
{
|
||||
float mean = 0, stdDev = 0, median = 0;
|
||||
|
||||
switch (m_histrogramMode)
|
||||
{
|
||||
case eHistogramMode_Luminosity:
|
||||
case eHistogramMode_SplitRGB:
|
||||
case eHistogramMode_OverlappedRGB:
|
||||
mean = m_histogram.m_meanAvg;
|
||||
stdDev = m_histogram.m_stdDevAvg;
|
||||
median = m_histogram.m_medianAvg;
|
||||
break;
|
||||
case eHistogramMode_RedChannel:
|
||||
mean = m_histogram.m_mean[0];
|
||||
stdDev = m_histogram.m_stdDev[0];
|
||||
median = m_histogram.m_median[0];
|
||||
break;
|
||||
case eHistogramMode_GreenChannel:
|
||||
mean = m_histogram.m_mean[1];
|
||||
stdDev = m_histogram.m_stdDev[1];
|
||||
median = m_histogram.m_median[1];
|
||||
break;
|
||||
case eHistogramMode_BlueChannel:
|
||||
mean = m_histogram.m_mean[2];
|
||||
stdDev = m_histogram.m_stdDev[2];
|
||||
median = m_histogram.m_median[2];
|
||||
break;
|
||||
case eHistogramMode_AlphaChannel:
|
||||
mean = m_histogram.m_mean[3];
|
||||
stdDev = m_histogram.m_stdDev[3];
|
||||
median = m_histogram.m_median[3];
|
||||
break;
|
||||
}
|
||||
QString val;
|
||||
val.setNum(mean);
|
||||
setMean(val);
|
||||
val.setNum(stdDev);
|
||||
setStdDev(val);
|
||||
val.setNum(median);
|
||||
setMedian(val);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Controls/moc_QBitmapPreviewDialogImp.cpp>
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef QBITMAPPREVIEWDIALOG_IMP_H
|
||||
#define QBITMAPPREVIEWDIALOG_IMP_H
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "QBitmapPreviewDialog.h"
|
||||
#include <Util/ImageHistogram.h>
|
||||
#endif
|
||||
|
||||
class CImageEx;
|
||||
|
||||
class QBitmapPreviewDialogImp
|
||||
: public QBitmapPreviewDialog
|
||||
{
|
||||
Q_OBJECT;
|
||||
public:
|
||||
|
||||
enum EUIStyle
|
||||
{
|
||||
EUISTYLE_IMAGE_ONLY,
|
||||
EUISTYLE_IMAGE_HISTOGRAM,
|
||||
EUISTYLE_NumModes
|
||||
};
|
||||
|
||||
enum EShowMode
|
||||
{
|
||||
ESHOW_RGB = 0,
|
||||
ESHOW_ALPHA,
|
||||
ESHOW_RGBA,
|
||||
ESHOW_RGB_ALPHA,
|
||||
ESHOW_RGBE,
|
||||
ESHOW_NumModes,
|
||||
};
|
||||
|
||||
enum EHistogramMode
|
||||
{
|
||||
eHistogramMode_Luminosity,
|
||||
eHistogramMode_OverlappedRGB,
|
||||
eHistogramMode_SplitRGB,
|
||||
eHistogramMode_RedChannel,
|
||||
eHistogramMode_GreenChannel,
|
||||
eHistogramMode_BlueChannel,
|
||||
eHistogramMode_AlphaChannel,
|
||||
eHistogramMode_NumModes,
|
||||
};
|
||||
|
||||
explicit QBitmapPreviewDialogImp(QWidget* parent = 0);
|
||||
virtual ~QBitmapPreviewDialogImp();
|
||||
|
||||
void setImage(const QString path);
|
||||
|
||||
void setShowMode(EShowMode mode);
|
||||
void toggleShowMode();
|
||||
void setUIStyleMode(EUIStyle mode);
|
||||
const EShowMode& getShowMode() const;
|
||||
|
||||
void setHistogramMode(EHistogramMode mode);
|
||||
void toggleHistrogramMode();
|
||||
const EHistogramMode& getHistogramMode() const;
|
||||
|
||||
void setOriginalSize(bool value);
|
||||
void toggleOriginalSize();
|
||||
|
||||
bool isSizeSmallerThanDefault();
|
||||
void paintEvent(QPaintEvent* e) override;
|
||||
|
||||
protected:
|
||||
void refreshData();
|
||||
|
||||
private:
|
||||
const char* GetShowModeDescription(EShowMode eShowMode, bool bShowInOriginalSize) const;
|
||||
|
||||
private:
|
||||
CImageEx* m_image;
|
||||
QString m_path;
|
||||
CImageHistogram m_histogram;
|
||||
bool m_showOriginalSize;
|
||||
EShowMode m_showMode;
|
||||
EHistogramMode m_histrogramMode;
|
||||
EUIStyle m_uiStyle;
|
||||
};
|
||||
|
||||
#endif // QBITMAPPREVIEWDIALOG_IMP_H
|
||||
@@ -1,642 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include <Controls/QToolTipWidget.h>
|
||||
|
||||
#include "QBitmapPreviewDialogImp.h"
|
||||
#include "qcoreapplication.h"
|
||||
#include "qguiapplication.h"
|
||||
#include "qapplication.h"
|
||||
#include <QDesktopWidget>
|
||||
#include <QPainter>
|
||||
#include <QtGlobal>
|
||||
#include <qgraphicseffect.h>
|
||||
|
||||
void QToolTipWidget::RebuildLayout()
|
||||
{
|
||||
if (m_title != nullptr)
|
||||
{
|
||||
m_title->hide();
|
||||
}
|
||||
if (m_content != nullptr)
|
||||
{
|
||||
m_content->hide();
|
||||
}
|
||||
if (m_specialContent != nullptr)
|
||||
{
|
||||
m_specialContent->hide();
|
||||
}
|
||||
|
||||
//empty layout
|
||||
while (m_layout->count() > 0)
|
||||
{
|
||||
m_layout->takeAt(0);
|
||||
}
|
||||
qDeleteAll(m_currentShortcuts);
|
||||
m_currentShortcuts.clear();
|
||||
if (m_includeTextureShortcuts)
|
||||
{
|
||||
m_currentShortcuts.append(new QLabel(tr("Alt - Alpha"), this));
|
||||
m_currentShortcuts.back()->setProperty("tooltipLabel", "Shortcut");
|
||||
m_currentShortcuts.append(new QLabel(tr("Shift - RGBA"), this));
|
||||
m_currentShortcuts.back()->setProperty("tooltipLabel", "Shortcut");
|
||||
}
|
||||
|
||||
if (m_title != nullptr && !m_title->text().isEmpty())
|
||||
{
|
||||
m_layout->addWidget(m_title);
|
||||
m_title->show();
|
||||
}
|
||||
|
||||
for (QLabel* var : m_currentShortcuts)
|
||||
{
|
||||
if (var != nullptr)
|
||||
{
|
||||
m_layout->addWidget(var);
|
||||
var->show();
|
||||
}
|
||||
}
|
||||
if (m_specialContent != nullptr)
|
||||
{
|
||||
m_layout->addWidget(m_specialContent);
|
||||
m_specialContent->show();
|
||||
}
|
||||
if (m_content != nullptr && !m_content->text().isEmpty())
|
||||
{
|
||||
m_layout->addWidget(m_content);
|
||||
m_content->show();
|
||||
}
|
||||
m_background->adjustSize();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void QToolTipWidget::Hide()
|
||||
{
|
||||
m_currentShortcuts.clear();
|
||||
hide();
|
||||
}
|
||||
|
||||
void QToolTipWidget::Show(QPoint pos, ArrowDirection dir)
|
||||
{
|
||||
if (!IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_arrow->m_direction = dir;
|
||||
pos = AdjustTipPosByArrowSize(pos, dir);
|
||||
m_normalPos = pos;
|
||||
move(pos);
|
||||
RebuildLayout();
|
||||
show();
|
||||
m_arrow->show();
|
||||
}
|
||||
|
||||
void QToolTipWidget::Display(QRect targetRect, ArrowDirection preferredArrowDir)
|
||||
{
|
||||
if (!IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KeepTipOnScreen(targetRect, preferredArrowDir);
|
||||
|
||||
RebuildLayout();
|
||||
show();
|
||||
m_arrow->show();
|
||||
}
|
||||
|
||||
void QToolTipWidget::TryDisplay(QPoint mousePos, const QRect& rect, [[maybe_unused]] ArrowDirection preferredArrowDir)
|
||||
{
|
||||
if (rect.contains(mousePos))
|
||||
{
|
||||
Display(rect, QToolTipWidget::ArrowDirection::ARROW_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void QToolTipWidget::TryDisplay(QPoint mousePos, const QWidget* widget, ArrowDirection preferredArrowDir)
|
||||
{
|
||||
const QRect rect(widget->mapToGlobal(QPoint(0,0)), widget->size());
|
||||
TryDisplay(mousePos, rect, preferredArrowDir);
|
||||
}
|
||||
|
||||
void QToolTipWidget::SetTitle(QString title)
|
||||
{
|
||||
if (!title.isEmpty())
|
||||
{
|
||||
m_title->setText(title);
|
||||
}
|
||||
m_title->setProperty("tooltipLabel", "Title");
|
||||
|
||||
setWindowTitle("ToolTip - " + title);
|
||||
}
|
||||
|
||||
void QToolTipWidget::SetContent(QString content)
|
||||
{
|
||||
m_content->setWordWrap(true);
|
||||
|
||||
m_content->setProperty("tooltipLabel", "Content");
|
||||
//line-height is not supported via stylesheet so we use the html rich-text subset in QT for it.
|
||||
m_content->setText(QString("<span style=\"line-height: 14px;\">%1</span>").arg(content));
|
||||
}
|
||||
|
||||
void QToolTipWidget::AppendContent(QString content)
|
||||
{
|
||||
m_content->setText(m_content->text() + "\n\n" + content);
|
||||
update();
|
||||
RebuildLayout();
|
||||
m_content->update();
|
||||
m_content->repaint();
|
||||
}
|
||||
|
||||
QToolTipWidget::QToolTipWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_background = new QWidget(this);
|
||||
m_background->setProperty("tooltip", "Background");
|
||||
m_background->stackUnder(this);
|
||||
m_title = new QLabel(this);
|
||||
m_currentShortcuts = QVector<QLabel*>();
|
||||
m_content = new QLabel(this);
|
||||
m_specialContent = nullptr;
|
||||
setWindowTitle("ToolTip");
|
||||
setObjectName("ToolTip");
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_normalPos = QPoint(0, 0);
|
||||
m_arrow = new QArrow(m_background);
|
||||
setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
|
||||
m_arrow->setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
|
||||
m_arrow->setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
m_background->setLayout(m_layout);
|
||||
m_arrow->setObjectName("ToolTipArrow");
|
||||
m_background->setObjectName("ToolTipBackground");
|
||||
|
||||
//we need a drop shadow for the background
|
||||
QGraphicsDropShadowEffect* dropShadow = new QGraphicsDropShadowEffect(this);
|
||||
dropShadow->setBlurRadius(m_shadowRadius);
|
||||
dropShadow->setColor(Qt::black);
|
||||
dropShadow->setOffset(0);
|
||||
dropShadow->setEnabled(true);
|
||||
m_background->setGraphicsEffect(dropShadow);
|
||||
//we need a second drop shadow effect for the arrow
|
||||
dropShadow = new QGraphicsDropShadowEffect(m_arrow);
|
||||
dropShadow->setBlurRadius(m_shadowRadius);
|
||||
dropShadow->setColor(Qt::black);
|
||||
dropShadow->setOffset(0);
|
||||
dropShadow->setEnabled(true);
|
||||
m_arrow->setGraphicsEffect(dropShadow);
|
||||
}
|
||||
|
||||
QToolTipWidget::~QToolTipWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void QToolTipWidget::AddSpecialContent(QString type, QString dataStream)
|
||||
{
|
||||
if (type.isEmpty())
|
||||
{
|
||||
m_includeTextureShortcuts = false;
|
||||
if (m_specialContent != nullptr)
|
||||
{
|
||||
delete m_specialContent;
|
||||
m_specialContent = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (type == "TEXTURE")
|
||||
{
|
||||
if (m_specialContent == nullptr)
|
||||
{
|
||||
QCoreApplication::instance()->installEventFilter(this); //grab the event filter while displaying the advanced texture tooltip
|
||||
m_specialContent = new QBitmapPreviewDialogImp(this);
|
||||
}
|
||||
QString path(dataStream);
|
||||
qobject_cast<QBitmapPreviewDialogImp*>(m_specialContent)->setImage(path);
|
||||
// set default showmode to RGB
|
||||
qobject_cast<QBitmapPreviewDialogImp*>(m_specialContent)->setShowMode(QBitmapPreviewDialogImp::EShowMode::ESHOW_RGB);
|
||||
QString dir = (path.split("/").count() > path.split("\\").count()) ? path.split("/").back() : path.split("\\").back();
|
||||
SetTitle(dir);
|
||||
//always use default size but not image size
|
||||
qobject_cast<QBitmapPreviewDialogImp*>(m_specialContent)->setOriginalSize(false);
|
||||
m_includeTextureShortcuts = true;
|
||||
}
|
||||
else if (type == "ADD TO CONTENT")
|
||||
{
|
||||
AppendContent(dataStream);
|
||||
|
||||
m_includeTextureShortcuts = false;
|
||||
if (m_specialContent != nullptr)
|
||||
{
|
||||
delete m_specialContent;
|
||||
m_specialContent = nullptr;
|
||||
}
|
||||
}
|
||||
else if (type == "REPLACE TITLE")
|
||||
{
|
||||
SetTitle(dataStream);
|
||||
m_includeTextureShortcuts = false;
|
||||
if (m_specialContent != nullptr)
|
||||
{
|
||||
delete m_specialContent;
|
||||
m_specialContent = nullptr;
|
||||
}
|
||||
}
|
||||
else if (type == "REPLACE CONTENT")
|
||||
{
|
||||
SetContent(dataStream);
|
||||
m_includeTextureShortcuts = false;
|
||||
if (m_specialContent != nullptr)
|
||||
{
|
||||
delete m_specialContent;
|
||||
m_specialContent = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_includeTextureShortcuts = false;
|
||||
if (m_specialContent != nullptr)
|
||||
{
|
||||
delete m_specialContent;
|
||||
m_specialContent = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_special = type;
|
||||
}
|
||||
|
||||
|
||||
bool QToolTipWidget::eventFilter(QObject* obj, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
if (m_special == "TEXTURE" && m_specialContent != nullptr)
|
||||
{
|
||||
const QKeyEvent* ke = static_cast<QKeyEvent*>(event);
|
||||
Qt::KeyboardModifiers mods = ke->modifiers();
|
||||
if (mods & Qt::KeyboardModifier::AltModifier)
|
||||
{
|
||||
((QBitmapPreviewDialogImp*)m_specialContent)->setShowMode(QBitmapPreviewDialogImp::ESHOW_ALPHA);
|
||||
}
|
||||
else if (mods & Qt::KeyboardModifier::ShiftModifier && !(mods & Qt::KeyboardModifier::ControlModifier))
|
||||
{
|
||||
((QBitmapPreviewDialogImp*)m_specialContent)->setShowMode(QBitmapPreviewDialogImp::ESHOW_RGBA);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (event->type() == QEvent::KeyRelease)
|
||||
{
|
||||
if (m_special == "TEXTURE" && m_specialContent != nullptr)
|
||||
{
|
||||
const QKeyEvent* ke = static_cast<QKeyEvent*>(event);
|
||||
Qt::KeyboardModifiers mods = ke->modifiers();
|
||||
if (!(mods& Qt::KeyboardModifier::AltModifier) && !(mods & Qt::KeyboardModifier::ShiftModifier))
|
||||
{
|
||||
((QBitmapPreviewDialogImp*)m_specialContent)->setShowMode(QBitmapPreviewDialogImp::ESHOW_RGB);
|
||||
}
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void QToolTipWidget::hideEvent(QHideEvent* event)
|
||||
{
|
||||
QWidget::hideEvent(event);
|
||||
m_arrow->hide();
|
||||
}
|
||||
|
||||
void QToolTipWidget::UpdateOptionalData(QString optionalData)
|
||||
{
|
||||
AddSpecialContent(m_special, optionalData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
QPoint QToolTipWidget::AdjustTipPosByArrowSize(QPoint pos, ArrowDirection dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case QToolTipWidget::ArrowDirection::ARROW_UP:
|
||||
{
|
||||
m_arrow->move(pos);
|
||||
pos.setY(pos.y() + 10);
|
||||
m_arrow->setFixedSize(20, 10);
|
||||
pos -= QPoint(m_shadowRadius, m_shadowRadius);
|
||||
break;
|
||||
}
|
||||
case QToolTipWidget::ArrowDirection::ARROW_LEFT:
|
||||
{
|
||||
m_arrow->move(pos);
|
||||
pos.setX(pos.x() + 10);
|
||||
m_arrow->setFixedSize(10, 20);
|
||||
pos -= QPoint(m_shadowRadius, m_shadowRadius);
|
||||
break;
|
||||
}
|
||||
case QToolTipWidget::ArrowDirection::ARROW_RIGHT:
|
||||
{
|
||||
pos.setX(pos.x() - 10);
|
||||
m_arrow->move(QPoint(pos.x() + width(), pos.y()));
|
||||
m_arrow->setFixedSize(10, 20);
|
||||
pos -= QPoint(-m_shadowRadius, m_shadowRadius);
|
||||
break;
|
||||
}
|
||||
case QToolTipWidget::ArrowDirection::ARROW_DOWN:
|
||||
{
|
||||
pos.setY(pos.y() - 10);
|
||||
m_arrow->move(QPoint(pos.x(), pos.y() + height()));
|
||||
m_arrow->setFixedSize(20, 10);
|
||||
pos -= QPoint(m_shadowRadius, -m_shadowRadius);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_arrow->move(-10, -10);
|
||||
break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool QToolTipWidget::IsValid()
|
||||
{
|
||||
if (m_title->text().isEmpty() ||
|
||||
(m_content->text().isEmpty() && m_specialContent == nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QToolTipWidget::KeepTipOnScreen(QRect targetRect, ArrowDirection preferredArrowDir)
|
||||
{
|
||||
QRect desktop = QApplication::desktop()->availableGeometry(this);
|
||||
|
||||
if (this->isHidden())
|
||||
{
|
||||
setAttribute(Qt::WA_DontShowOnScreen, true);
|
||||
Show(QPoint(0, 0), preferredArrowDir);
|
||||
hide();
|
||||
setAttribute(Qt::WA_DontShowOnScreen, false);
|
||||
}
|
||||
//else assume the size is right
|
||||
|
||||
//calculate initial rect
|
||||
QRect tipRect = QRect(0, 0, 0, 0);
|
||||
switch (preferredArrowDir)
|
||||
{
|
||||
case QToolTipWidget::ArrowDirection::ARROW_UP:
|
||||
{
|
||||
//tip is below the widget with a left alignment
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(targetRect.bottomLeft(), preferredArrowDir));
|
||||
break;
|
||||
}
|
||||
case QToolTipWidget::ArrowDirection::ARROW_LEFT:
|
||||
{
|
||||
//tip is on the right with the top being even
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(targetRect.topRight(), preferredArrowDir));
|
||||
break;
|
||||
}
|
||||
case QToolTipWidget::ArrowDirection::ARROW_RIGHT:
|
||||
{
|
||||
//tip is on the left with the top being even
|
||||
tipRect.setY(targetRect.top());
|
||||
tipRect.setX(targetRect.left() - width());
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(tipRect.topLeft(), preferredArrowDir));
|
||||
break;
|
||||
}
|
||||
case QToolTipWidget::ArrowDirection::ARROW_DOWN:
|
||||
{
|
||||
//tip is above the widget with a left alignment
|
||||
tipRect.setX(targetRect.left());
|
||||
tipRect.setY(targetRect.top() - height());
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(tipRect.topLeft(), preferredArrowDir));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//tip is on the right with the top being even
|
||||
preferredArrowDir = QToolTipWidget::ArrowDirection::ARROW_LEFT;
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(targetRect.topRight(), QToolTipWidget::ArrowDirection::ARROW_LEFT));
|
||||
break;
|
||||
}
|
||||
}
|
||||
tipRect.setSize(size());
|
||||
|
||||
//FixPositioning
|
||||
if (preferredArrowDir == ArrowDirection::ARROW_LEFT || preferredArrowDir == ArrowDirection::ARROW_RIGHT)
|
||||
{
|
||||
if (tipRect.left() <= desktop.left())
|
||||
{
|
||||
m_arrow->m_direction = ArrowDirection::ARROW_LEFT;
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(targetRect.topRight(), m_arrow->m_direction));
|
||||
}
|
||||
else if (tipRect.right() >= desktop.right())
|
||||
{
|
||||
m_arrow->m_direction = ArrowDirection::ARROW_RIGHT;
|
||||
tipRect.setLeft(targetRect.left() - width());
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(tipRect.topLeft(), m_arrow->m_direction));
|
||||
}
|
||||
}
|
||||
else if (preferredArrowDir == ArrowDirection::ARROW_UP || preferredArrowDir == ArrowDirection::ARROW_DOWN)
|
||||
{
|
||||
if (tipRect.top() <= desktop.top())
|
||||
{
|
||||
m_arrow->m_direction = ArrowDirection::ARROW_UP;
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(targetRect.bottomLeft(), m_arrow->m_direction));
|
||||
}
|
||||
else if (tipRect.bottom() >= desktop.bottom())
|
||||
{
|
||||
m_arrow->m_direction = ArrowDirection::ARROW_DOWN;
|
||||
tipRect.setY(targetRect.top() - height());
|
||||
tipRect.setTopLeft(AdjustTipPosByArrowSize(tipRect.topLeft(), m_arrow->m_direction));
|
||||
}
|
||||
}
|
||||
|
||||
//Nudge tip without arrow
|
||||
if (preferredArrowDir == ArrowDirection::ARROW_UP || preferredArrowDir == ArrowDirection::ARROW_DOWN)
|
||||
{
|
||||
if (tipRect.left() <= desktop.left())
|
||||
{
|
||||
tipRect.setLeft(desktop.left());
|
||||
}
|
||||
else if (tipRect.right() >= desktop.right())
|
||||
{
|
||||
tipRect.setLeft(desktop.right() - width());
|
||||
}
|
||||
}
|
||||
else if (preferredArrowDir == ArrowDirection::ARROW_RIGHT || preferredArrowDir == ArrowDirection::ARROW_LEFT)
|
||||
{
|
||||
if (tipRect.top() <= desktop.top())
|
||||
{
|
||||
tipRect.setTop(desktop.top());
|
||||
}
|
||||
else if (tipRect.bottom() >= desktop.bottom())
|
||||
{
|
||||
tipRect.setTop(desktop.bottom() - height());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_normalPos = tipRect.topLeft();
|
||||
move(m_normalPos);
|
||||
}
|
||||
|
||||
QPolygonF QToolTipWidget::QArrow::CreateArrow()
|
||||
{
|
||||
QVector<QPointF> vertex;
|
||||
//3 points in triangle
|
||||
vertex.reserve(3);
|
||||
//all magic number below are given in order to draw smooth transitions between tooltip and arrow
|
||||
if (m_direction == ArrowDirection::ARROW_UP)
|
||||
{
|
||||
vertex.push_back(QPointF(10, 1));
|
||||
vertex.push_back(QPointF(19, 10));
|
||||
vertex.push_back(QPointF(0, 10));
|
||||
}
|
||||
else if (m_direction == ArrowDirection::ARROW_RIGHT)
|
||||
{
|
||||
vertex.push_back(QPointF(9, 10));
|
||||
vertex.push_back(QPointF(0, 19));
|
||||
vertex.push_back(QPointF(0, 1));
|
||||
}
|
||||
else if (m_direction == ArrowDirection::ARROW_LEFT)
|
||||
{
|
||||
vertex.push_back(QPointF(1, 10));
|
||||
vertex.push_back(QPointF(10, 19));
|
||||
vertex.push_back(QPointF(10, 0));
|
||||
}
|
||||
else //ArrowDirection::ARROW_DOWN
|
||||
{
|
||||
vertex.push_back(QPointF(10, 10));
|
||||
vertex.push_back(QPointF(19, 0));
|
||||
vertex.push_back(QPointF(0, 0));
|
||||
}
|
||||
return QPolygonF(vertex);
|
||||
}
|
||||
|
||||
void QToolTipWidget::QArrow::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
{
|
||||
QColor color(255, 255, 255, 255);
|
||||
QPainter painter(this);
|
||||
painter.fillRect(rect(), Qt::transparent); //force transparency
|
||||
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
painter.setBrush(color);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawPolygon(CreateArrow());
|
||||
//painter.setRenderHint(QPainter::Antialiasing, false);
|
||||
}
|
||||
|
||||
QToolTipWrapper::QToolTipWrapper(QWidget* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void QToolTipWrapper::SetTitle(QString title)
|
||||
{
|
||||
m_title = title;
|
||||
}
|
||||
|
||||
void QToolTipWrapper::SetContent(QString content)
|
||||
{
|
||||
AddSpecialContent("REPLACE CONTENT", content);
|
||||
}
|
||||
|
||||
void QToolTipWrapper::AppendContent(QString content)
|
||||
{
|
||||
AddSpecialContent("ADD TO CONTENT", content);
|
||||
}
|
||||
|
||||
void QToolTipWrapper::AddSpecialContent(QString type, QString dataStream)
|
||||
{
|
||||
if (type == "REPLACE CONTENT")
|
||||
{
|
||||
m_contentOperations.clear();
|
||||
}
|
||||
m_contentOperations.push_back({type, dataStream});
|
||||
}
|
||||
|
||||
void QToolTipWrapper::UpdateOptionalData(QString optionalData)
|
||||
{
|
||||
m_contentOperations.push_back({"UPDATE OPTIONAL", optionalData});
|
||||
}
|
||||
|
||||
void QToolTipWrapper::Display(QRect targetRect, QToolTipWidget::ArrowDirection preferredArrowDir)
|
||||
{
|
||||
GetOrCreateToolTip()->Display(targetRect, preferredArrowDir);
|
||||
}
|
||||
|
||||
void QToolTipWrapper::TryDisplay(QPoint mousePos, const QWidget * widget, QToolTipWidget::ArrowDirection preferredArrowDir)
|
||||
{
|
||||
GetOrCreateToolTip()->TryDisplay(mousePos, widget, preferredArrowDir);
|
||||
}
|
||||
|
||||
void QToolTipWrapper::TryDisplay(QPoint mousePos, const QRect & widget, QToolTipWidget::ArrowDirection preferredArrowDir)
|
||||
{
|
||||
GetOrCreateToolTip()->TryDisplay(mousePos, widget, preferredArrowDir);
|
||||
}
|
||||
|
||||
void QToolTipWrapper::hide()
|
||||
{
|
||||
DestroyToolTip();
|
||||
}
|
||||
|
||||
void QToolTipWrapper::show()
|
||||
{
|
||||
GetOrCreateToolTip()->show();
|
||||
}
|
||||
|
||||
bool QToolTipWrapper::isVisible() const
|
||||
{
|
||||
return m_actualTooltip && m_actualTooltip->isVisible();
|
||||
}
|
||||
|
||||
void QToolTipWrapper::update()
|
||||
{
|
||||
if (m_actualTooltip)
|
||||
{
|
||||
m_actualTooltip->update();
|
||||
}
|
||||
}
|
||||
|
||||
void QToolTipWrapper::ReplayContentOperations(QToolTipWidget* tooltipWidget)
|
||||
{
|
||||
tooltipWidget->SetTitle(m_title);
|
||||
for (const auto& operation : m_contentOperations)
|
||||
{
|
||||
if (operation.first == "UPDATE OPTIONAL")
|
||||
{
|
||||
tooltipWidget->UpdateOptionalData(operation.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
tooltipWidget->AddSpecialContent(operation.first, operation.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QToolTipWidget * QToolTipWrapper::GetOrCreateToolTip()
|
||||
{
|
||||
if (!m_actualTooltip)
|
||||
{
|
||||
QToolTipWidget* tooltipWidget = new QToolTipWidget(static_cast<QWidget*>(parent()));
|
||||
tooltipWidget->setAttribute(Qt::WA_DeleteOnClose);
|
||||
ReplayContentOperations(tooltipWidget);
|
||||
m_actualTooltip = tooltipWidget;
|
||||
}
|
||||
return m_actualTooltip.data();
|
||||
}
|
||||
|
||||
void QToolTipWrapper::DestroyToolTip()
|
||||
{
|
||||
if (m_actualTooltip)
|
||||
{
|
||||
m_actualTooltip->deleteLater();
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef QToolTipWidget_h__
|
||||
#define QToolTipWidget_h__
|
||||
|
||||
#include "EditorCoreAPI.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QMapIterator>
|
||||
#include <QVector>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class IQToolTip
|
||||
{
|
||||
public:
|
||||
virtual void SetTitle(QString title) = 0;
|
||||
virtual void SetContent(QString content) = 0;
|
||||
virtual void AppendContent(QString content) = 0;
|
||||
virtual void AddSpecialContent(QString type, QString dataStream) = 0;
|
||||
virtual void UpdateOptionalData(QString optionalData) = 0;
|
||||
};
|
||||
|
||||
class EDITOR_CORE_API QToolTipWidget
|
||||
: public QWidget
|
||||
, public IQToolTip
|
||||
{
|
||||
public:
|
||||
enum class ArrowDirection
|
||||
{
|
||||
ARROW_UP,
|
||||
ARROW_LEFT,
|
||||
ARROW_RIGHT,
|
||||
ARROW_DOWN
|
||||
};
|
||||
class QArrow
|
||||
: public QWidget
|
||||
{
|
||||
public:
|
||||
ArrowDirection m_direction;
|
||||
QPoint m_pos;
|
||||
QArrow(QWidget* parent)
|
||||
: QWidget(parent){ setWindowFlags(Qt::ToolTip); }
|
||||
virtual ~QArrow(){}
|
||||
|
||||
QPolygonF CreateArrow();
|
||||
virtual void paintEvent(QPaintEvent*) override;
|
||||
};
|
||||
QToolTipWidget(QWidget* parent);
|
||||
~QToolTipWidget();
|
||||
void SetTitle(QString title) override;
|
||||
void SetContent(QString content) override;
|
||||
void AppendContent(QString content) override;
|
||||
void AddSpecialContent(QString type, QString dataStream) override;
|
||||
void UpdateOptionalData(QString optionalData) override;
|
||||
void Display(QRect targetRect, ArrowDirection preferredArrowDir);
|
||||
|
||||
//! Displays the tooltip on the given widget, only if the mouse is over it.
|
||||
void TryDisplay(QPoint mousePos, const QWidget* widget, ArrowDirection preferredArrowDir);
|
||||
|
||||
//! Displays the tooltip on the given rect, only if the mouse is over it.
|
||||
void TryDisplay(QPoint mousePos, const QRect& widget, ArrowDirection preferredArrowDir);
|
||||
|
||||
void Hide();
|
||||
|
||||
protected:
|
||||
void Show(QPoint pos, ArrowDirection dir);
|
||||
bool IsValid();
|
||||
void KeepTipOnScreen(QRect targetRect, ArrowDirection preferredArrowDir);
|
||||
QPoint AdjustTipPosByArrowSize(QPoint pos, ArrowDirection dir);
|
||||
virtual bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
void RebuildLayout();
|
||||
virtual void hideEvent(QHideEvent*) override;
|
||||
|
||||
QLabel* m_title;
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QVector<QLabel*> m_currentShortcuts;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
//can be anything from QLabel to QBitMapPreviewDialog
|
||||
//must allow movement, and show/hide calls
|
||||
QLabel* m_content;
|
||||
QWidget* m_specialContent;
|
||||
QWidget* m_background;
|
||||
QVBoxLayout* m_layout;
|
||||
QString m_special;
|
||||
QPoint m_normalPos;
|
||||
QArrow* m_arrow;
|
||||
const int m_shadowRadius = 5;
|
||||
bool m_includeTextureShortcuts; //added since Qt does not support modifier only shortcuts
|
||||
};
|
||||
|
||||
// HACK: The EditorUI_QT classes all were keeping persistent references to QToolTipWidgets around
|
||||
// This led to many, many top-level widget creations, which led to many platform-side window allocations
|
||||
// which led to crashes in Qt5.15. As this is legacy code, this is a drop-in replacement that only
|
||||
// allocates the actual QToolTipWidget (and thus platform window) while the tooltip is visible
|
||||
class EDITOR_CORE_API QToolTipWrapper
|
||||
: public QObject
|
||||
, public IQToolTip
|
||||
{
|
||||
public:
|
||||
QToolTipWrapper(QWidget* parent);
|
||||
|
||||
void SetTitle(QString title) override;
|
||||
void SetContent(QString content) override;
|
||||
void AppendContent(QString content) override;
|
||||
void AddSpecialContent(QString type, QString dataStream) override;
|
||||
void UpdateOptionalData(QString optionalData) override;
|
||||
|
||||
void Display(QRect targetRect, QToolTipWidget::ArrowDirection preferredArrowDir);
|
||||
void TryDisplay(QPoint mousePos, const QWidget* widget, QToolTipWidget::ArrowDirection preferredArrowDir);
|
||||
void TryDisplay(QPoint mousePos, const QRect& widget, QToolTipWidget::ArrowDirection preferredArrowDir);
|
||||
void hide();
|
||||
void show();
|
||||
bool isVisible() const;
|
||||
void update();
|
||||
void repaint(){update();} //Things really shouldn't be calling repaint on these...
|
||||
|
||||
void Hide(){hide();}
|
||||
void close(){hide();}
|
||||
|
||||
private:
|
||||
void ReplayContentOperations(QToolTipWidget* tooltipWidget);
|
||||
|
||||
QToolTipWidget* GetOrCreateToolTip();
|
||||
void DestroyToolTip();
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // conditional expression is constant, needs to have dll-interface to be used by clients of class 'AzQtComponents::FilteredSearchWidget'
|
||||
QPointer<QToolTipWidget> m_actualTooltip;
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
QString m_title;
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // conditional expression is constant, needs to have dll-interface to be used by clients of class 'AzQtComponents::FilteredSearchWidget'
|
||||
QVector<QPair<QString, QString>> m_contentOperations;
|
||||
AZ_POP_DISABLE_WARNING
|
||||
};
|
||||
|
||||
|
||||
#endif // QToolTipWidget_h__
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "PropertyAnimationCtrl.h"
|
||||
|
||||
// Qt
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
|
||||
// Editor
|
||||
#include "Util/UIEnumerations.h"
|
||||
#include "IResourceSelectorHost.h"
|
||||
|
||||
AnimationPropertyCtrl::AnimationPropertyCtrl(QWidget *pParent)
|
||||
: QWidget(pParent)
|
||||
{
|
||||
m_animationLabel = new QLabel;
|
||||
|
||||
m_pApplyButton = new QToolButton;
|
||||
m_pApplyButton->setIcon(QIcon(":/reflectedPropertyCtrl/img/apply.png"));
|
||||
|
||||
m_pApplyButton->setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
QHBoxLayout *pLayout = new QHBoxLayout(this);
|
||||
pLayout->setContentsMargins(0, 0, 0, 0);
|
||||
pLayout->addWidget(m_animationLabel, 1);
|
||||
pLayout->addWidget(m_pApplyButton);
|
||||
|
||||
connect(m_pApplyButton, &QAbstractButton::clicked, this, &AnimationPropertyCtrl::OnApplyClicked);
|
||||
};
|
||||
|
||||
AnimationPropertyCtrl::~AnimationPropertyCtrl()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void AnimationPropertyCtrl::SetValue(const CReflectedVarAnimation &animation)
|
||||
{
|
||||
m_animation = animation;
|
||||
m_animationLabel->setText(animation.m_animation.c_str());
|
||||
}
|
||||
|
||||
CReflectedVarAnimation AnimationPropertyCtrl::value() const
|
||||
{
|
||||
return m_animation;
|
||||
}
|
||||
|
||||
void AnimationPropertyCtrl::OnApplyClicked()
|
||||
{
|
||||
QStringList cSelectedAnimations;
|
||||
int nTotalAnimations(0);
|
||||
int nCurrentAnimation(0);
|
||||
|
||||
QString combinedString = GetIEditor()->GetResourceSelectorHost()->GetGlobalSelection("animation");
|
||||
SplitString(combinedString, cSelectedAnimations, ',');
|
||||
|
||||
nTotalAnimations = cSelectedAnimations.size();
|
||||
for (nCurrentAnimation = 0; nCurrentAnimation < nTotalAnimations; ++nCurrentAnimation)
|
||||
{
|
||||
QString& rstrCurrentAnimAction = cSelectedAnimations[nCurrentAnimation];
|
||||
if (!rstrCurrentAnimAction.isEmpty())
|
||||
{
|
||||
m_animation.m_animation = rstrCurrentAnimAction.toUtf8().data();
|
||||
m_animationLabel->setText(m_animation.m_animation.c_str());
|
||||
emit ValueChanged(m_animation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* AnimationPropertyCtrl::GetFirstInTabOrder()
|
||||
{
|
||||
return m_pApplyButton;
|
||||
}
|
||||
QWidget* AnimationPropertyCtrl::GetLastInTabOrder()
|
||||
{
|
||||
return m_pApplyButton;
|
||||
}
|
||||
|
||||
void AnimationPropertyCtrl::UpdateTabOrder()
|
||||
{
|
||||
setTabOrder(m_pApplyButton, m_pApplyButton);
|
||||
}
|
||||
|
||||
|
||||
QWidget* AnimationPropertyWidgetHandler::CreateGUI(QWidget *pParent)
|
||||
{
|
||||
AnimationPropertyCtrl* newCtrl = aznew AnimationPropertyCtrl(pParent);
|
||||
connect(newCtrl, &AnimationPropertyCtrl::ValueChanged, newCtrl, [newCtrl]()
|
||||
{
|
||||
EBUS_EVENT(AzToolsFramework::PropertyEditorGUIMessages::Bus, RequestWrite, newCtrl);
|
||||
});
|
||||
return newCtrl;
|
||||
}
|
||||
|
||||
|
||||
void AnimationPropertyWidgetHandler::ConsumeAttribute(AnimationPropertyCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName)
|
||||
{
|
||||
Q_UNUSED(GUI);
|
||||
Q_UNUSED(attrib);
|
||||
Q_UNUSED(attrValue);
|
||||
Q_UNUSED(debugName);
|
||||
}
|
||||
|
||||
void AnimationPropertyWidgetHandler::WriteGUIValuesIntoProperty(size_t index, AnimationPropertyCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_UNUSED(node);
|
||||
CReflectedVarAnimation val = GUI->value();
|
||||
instance = static_cast<property_t>(val);
|
||||
}
|
||||
|
||||
bool AnimationPropertyWidgetHandler::ReadValuesIntoGUI(size_t index, AnimationPropertyCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_UNUSED(node);
|
||||
CReflectedVarAnimation val = instance;
|
||||
GUI->SetValue(val);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#include <Controls/ReflectedPropertyControl/moc_PropertyAnimationCtrl.cpp>
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_UTILS_PROPERTYANIMATIONCTRL_H
|
||||
#define CRYINCLUDE_EDITOR_UTILS_PROPERTYANIMATIONCTRL_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include "ReflectedVar.h"
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
#endif
|
||||
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
class QHBoxLayout;
|
||||
|
||||
class AnimationPropertyCtrl
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AnimationPropertyCtrl, AZ::SystemAllocator, 0);
|
||||
|
||||
AnimationPropertyCtrl(QWidget* pParent = nullptr);
|
||||
virtual ~AnimationPropertyCtrl();
|
||||
|
||||
CReflectedVarAnimation value() const;
|
||||
|
||||
QWidget* GetFirstInTabOrder();
|
||||
QWidget* GetLastInTabOrder();
|
||||
void UpdateTabOrder();
|
||||
|
||||
signals:
|
||||
void ValueChanged(CReflectedVarAnimation value);
|
||||
|
||||
public slots:
|
||||
void SetValue(const CReflectedVarAnimation& animation);
|
||||
|
||||
protected slots:
|
||||
void OnApplyClicked();
|
||||
|
||||
private:
|
||||
QToolButton* m_pApplyButton;
|
||||
QLabel* m_animationLabel;
|
||||
|
||||
CReflectedVarAnimation m_animation;
|
||||
};
|
||||
|
||||
class AnimationPropertyWidgetHandler
|
||||
: QObject
|
||||
, public AzToolsFramework::PropertyHandler < CReflectedVarAnimation, AnimationPropertyCtrl >
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AnimationPropertyWidgetHandler, AZ::SystemAllocator, 0);
|
||||
|
||||
virtual AZ::u32 GetHandlerName(void) const override { return AZ_CRC("Animation", 0x8d5284dc); }
|
||||
virtual bool IsDefaultHandler() const override { return true; }
|
||||
virtual QWidget* GetFirstInTabOrder(AnimationPropertyCtrl* widget) override { return widget->GetFirstInTabOrder(); }
|
||||
virtual QWidget* GetLastInTabOrder(AnimationPropertyCtrl* widget) override { return widget->GetLastInTabOrder(); }
|
||||
virtual void UpdateWidgetInternalTabbing(AnimationPropertyCtrl* widget) override { widget->UpdateTabOrder(); }
|
||||
|
||||
virtual QWidget* CreateGUI(QWidget* pParent) override;
|
||||
virtual void ConsumeAttribute(AnimationPropertyCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override;
|
||||
virtual void WriteGUIValuesIntoProperty(size_t index, AnimationPropertyCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
virtual bool ReadValuesIntoGUI(size_t index, AnimationPropertyCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_UTILS_PROPERTYANIMATIONCTRL_H
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
// Editor
|
||||
#include "PropertyCtrl.h"
|
||||
#include "PropertyResourceCtrl.h"
|
||||
#include "PropertyGenericCtrl.h"
|
||||
#include "PropertyMiscCtrl.h"
|
||||
#include "PropertyMotionCtrl.h"
|
||||
@@ -21,7 +20,6 @@ void RegisterReflectedVarHandlers()
|
||||
if (!registered)
|
||||
{
|
||||
registered = true;
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew FileResourceSelectorWidgetHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequencePropertyHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequenceIdPropertyHandler());
|
||||
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew LocalStringPropertyHandler());
|
||||
|
||||
@@ -1,383 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "PropertyResourceCtrl.h"
|
||||
|
||||
// Qt
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyAudioCtrl.h>
|
||||
|
||||
// Editor
|
||||
#include "Controls/QToolTipWidget.h"
|
||||
#include "Controls/BitmapToolTip.h"
|
||||
|
||||
|
||||
BrowseButton::BrowseButton(PropertyType type, QWidget* parent /*= nullptr*/)
|
||||
: QToolButton(parent)
|
||||
, m_propertyType(type)
|
||||
{
|
||||
setAutoRaise(true);
|
||||
setIcon(QIcon(QStringLiteral(":/stylesheet/img/UI20/browse-edit.svg")));
|
||||
connect(this, &QAbstractButton::clicked, this, &BrowseButton::OnClicked);
|
||||
}
|
||||
|
||||
void BrowseButton::SetPathAndEmit(const QString& path)
|
||||
{
|
||||
//only emit if path changes. Old property control
|
||||
if (path != m_path)
|
||||
{
|
||||
m_path = path;
|
||||
emit PathChanged(m_path);
|
||||
}
|
||||
}
|
||||
|
||||
class FileBrowseButton
|
||||
: public BrowseButton
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FileBrowseButton, AZ::SystemAllocator, 0);
|
||||
FileBrowseButton(PropertyType type, QWidget* pParent = nullptr)
|
||||
: BrowseButton(type, pParent)
|
||||
{
|
||||
setToolTip("Browse...");
|
||||
}
|
||||
|
||||
private:
|
||||
void OnClicked() override
|
||||
{
|
||||
QString tempValue("");
|
||||
if (!m_path.isEmpty() && !Path::GetExt(m_path).isEmpty())
|
||||
{
|
||||
tempValue = m_path;
|
||||
}
|
||||
|
||||
AssetSelectionModel selection;
|
||||
|
||||
if (m_propertyType == ePropertyTexture)
|
||||
{
|
||||
// Filters for texture.
|
||||
selection = AssetSelectionModel::AssetGroupSelection("Texture");
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
||||
if (selection.IsValid())
|
||||
{
|
||||
QString newPath = Path::FullPathToGamePath(selection.GetResult()->GetFullPath().c_str()).c_str();
|
||||
|
||||
switch (m_propertyType)
|
||||
{
|
||||
case ePropertyTexture:
|
||||
newPath.replace("\\\\", "/");
|
||||
if (newPath.size() > MAX_PATH)
|
||||
{
|
||||
newPath.resize(MAX_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
SetPathAndEmit(newPath);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class AudioControlSelectorButton
|
||||
: public BrowseButton
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AudioControlSelectorButton, AZ::SystemAllocator, 0);
|
||||
|
||||
AudioControlSelectorButton(PropertyType type, QWidget* pParent = nullptr)
|
||||
: BrowseButton(type, pParent)
|
||||
{
|
||||
setToolTip(tr("Select Audio Control"));
|
||||
}
|
||||
|
||||
private:
|
||||
void OnClicked() override
|
||||
{
|
||||
AZStd::string resourceResult;
|
||||
auto ConvertLegacyAudioPropertyType = [](const PropertyType type) -> AzToolsFramework::AudioPropertyType
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ePropertyAudioTrigger:
|
||||
return AzToolsFramework::AudioPropertyType::Trigger;
|
||||
case ePropertyAudioRTPC:
|
||||
return AzToolsFramework::AudioPropertyType::Rtpc;
|
||||
case ePropertyAudioSwitch:
|
||||
return AzToolsFramework::AudioPropertyType::Switch;
|
||||
case ePropertyAudioSwitchState:
|
||||
return AzToolsFramework::AudioPropertyType::SwitchState;
|
||||
case ePropertyAudioEnvironment:
|
||||
return AzToolsFramework::AudioPropertyType::Environment;
|
||||
case ePropertyAudioPreloadRequest:
|
||||
return AzToolsFramework::AudioPropertyType::Preload;
|
||||
default:
|
||||
return AzToolsFramework::AudioPropertyType::NumTypes;
|
||||
}
|
||||
};
|
||||
|
||||
auto propType = ConvertLegacyAudioPropertyType(m_propertyType);
|
||||
if (propType != AzToolsFramework::AudioPropertyType::NumTypes)
|
||||
{
|
||||
AzToolsFramework::AudioControlSelectorRequestBus::EventResult(
|
||||
resourceResult, propType, &AzToolsFramework::AudioControlSelectorRequestBus::Events::SelectResource,
|
||||
AZStd::string_view{ m_path.toUtf8().constData() });
|
||||
SetPathAndEmit(QString{ resourceResult.c_str() });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class TextureEditButton
|
||||
: public BrowseButton
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(TextureEditButton, AZ::SystemAllocator, 0);
|
||||
TextureEditButton(QWidget* pParent = nullptr)
|
||||
: BrowseButton(ePropertyTexture, pParent)
|
||||
{
|
||||
setIcon(QIcon(QStringLiteral(":/stylesheet/img/UI20/open-in-internal-app.svg")));
|
||||
setToolTip(tr("Launch default editor"));
|
||||
}
|
||||
|
||||
private:
|
||||
void OnClicked() override
|
||||
{
|
||||
CFileUtil::EditTextureFile(m_path.toUtf8().data(), true);
|
||||
}
|
||||
};
|
||||
|
||||
FileResourceSelectorWidget::FileResourceSelectorWidget(QWidget* pParent /*= nullptr*/)
|
||||
: QWidget(pParent)
|
||||
, m_propertyType(ePropertyInvalid)
|
||||
, m_tooltip(nullptr)
|
||||
{
|
||||
m_pathEdit = new QLineEdit;
|
||||
m_mainLayout = new QHBoxLayout(this);
|
||||
m_mainLayout->addWidget(m_pathEdit, 1);
|
||||
|
||||
m_mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
// KDAB just ported the MFC texture preview tooltip, but looks like Amazon added their own. Not sure which to use.
|
||||
// To switch to Amazon QToolTipWidget, remove FileResourceSelectorWidget::event and m_previewTooltip
|
||||
#ifdef USE_QTOOLTIPWIDGET
|
||||
m_tooltip = new QToolTipWidget(this);
|
||||
|
||||
installEventFilter(this);
|
||||
#endif
|
||||
connect(m_pathEdit, &QLineEdit::editingFinished, this, [this]() { OnPathChanged(m_pathEdit->text()); });
|
||||
}
|
||||
|
||||
bool FileResourceSelectorWidget::eventFilter([[maybe_unused]] QObject* obj, QEvent* event)
|
||||
{
|
||||
if (m_propertyType == ePropertyTexture)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip)
|
||||
{
|
||||
QHelpEvent* e = (QHelpEvent*)event;
|
||||
|
||||
m_tooltip->AddSpecialContent("TEXTURE", m_path);
|
||||
m_tooltip->TryDisplay(e->globalPos(), m_pathEdit, QToolTipWidget::ArrowDirection::ARROW_RIGHT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::Leave)
|
||||
{
|
||||
m_tooltip->hide();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileResourceSelectorWidget::SetPropertyType(PropertyType type)
|
||||
{
|
||||
if (m_propertyType == type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//if the property type changed for some reason, delete all the existing widgets
|
||||
if (!m_buttons.isEmpty())
|
||||
{
|
||||
qDeleteAll(m_buttons.begin(), m_buttons.end());
|
||||
m_buttons.clear();
|
||||
}
|
||||
|
||||
m_previewToolTip.reset();
|
||||
m_propertyType = type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ePropertyTexture:
|
||||
AddButton(new FileBrowseButton(type));
|
||||
AddButton(new TextureEditButton);
|
||||
m_previewToolTip.reset(new CBitmapToolTip);
|
||||
break;
|
||||
case ePropertyAudioTrigger:
|
||||
case ePropertyAudioSwitch:
|
||||
case ePropertyAudioSwitchState:
|
||||
case ePropertyAudioRTPC:
|
||||
case ePropertyAudioEnvironment:
|
||||
case ePropertyAudioPreloadRequest:
|
||||
AddButton(new AudioControlSelectorButton(type));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_mainLayout->invalidate();
|
||||
}
|
||||
|
||||
void FileResourceSelectorWidget::AddButton(BrowseButton* button)
|
||||
{
|
||||
m_mainLayout->addWidget(button);
|
||||
m_buttons.push_back(button);
|
||||
connect(button, &BrowseButton::PathChanged, this, &FileResourceSelectorWidget::OnPathChanged);
|
||||
}
|
||||
|
||||
void FileResourceSelectorWidget::OnPathChanged(const QString& path)
|
||||
{
|
||||
bool changed = SetPath(path);
|
||||
if (changed)
|
||||
{
|
||||
emit PathChanged(m_path);
|
||||
}
|
||||
}
|
||||
|
||||
bool FileResourceSelectorWidget::SetPath(const QString& path)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
const QString newPath = path.toLower();
|
||||
if (m_path != newPath)
|
||||
{
|
||||
m_path = newPath;
|
||||
UpdateWidgets();
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
void FileResourceSelectorWidget::UpdateWidgets()
|
||||
{
|
||||
m_pathEdit->setText(m_path);
|
||||
|
||||
foreach(BrowseButton * button, m_buttons)
|
||||
{
|
||||
button->SetPath(m_path);
|
||||
}
|
||||
|
||||
if (m_previewToolTip)
|
||||
{
|
||||
m_previewToolTip->SetTool(this, rect());
|
||||
}
|
||||
}
|
||||
|
||||
QString FileResourceSelectorWidget::GetPath() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QWidget* FileResourceSelectorWidget::GetLastInTabOrder()
|
||||
{
|
||||
return m_buttons.empty() ? nullptr : m_buttons.last();
|
||||
}
|
||||
|
||||
QWidget* FileResourceSelectorWidget::GetFirstInTabOrder()
|
||||
{
|
||||
return m_buttons.empty() ? nullptr : m_buttons.first();
|
||||
}
|
||||
|
||||
void FileResourceSelectorWidget::UpdateTabOrder()
|
||||
{
|
||||
if (m_buttons.count() >= 2)
|
||||
{
|
||||
for (int i = 0; i < m_buttons.count() - 1; ++i)
|
||||
{
|
||||
setTabOrder(m_buttons[i], m_buttons[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FileResourceSelectorWidget::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip && m_previewToolTip && !m_previewToolTip->isVisible())
|
||||
{
|
||||
if (!m_path.isEmpty())
|
||||
{
|
||||
m_previewToolTip->LoadImage(m_path);
|
||||
m_previewToolTip->setVisible(true);
|
||||
}
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::Resize && m_previewToolTip)
|
||||
{
|
||||
m_previewToolTip->SetTool(this, rect());
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
QWidget* FileResourceSelectorWidgetHandler::CreateGUI(QWidget* pParent)
|
||||
{
|
||||
FileResourceSelectorWidget* newCtrl = aznew FileResourceSelectorWidget(pParent);
|
||||
connect(newCtrl, &FileResourceSelectorWidget::PathChanged, newCtrl, [newCtrl]()
|
||||
{
|
||||
EBUS_EVENT(AzToolsFramework::PropertyEditorGUIMessages::Bus, RequestWrite, newCtrl);
|
||||
});
|
||||
return newCtrl;
|
||||
}
|
||||
|
||||
void FileResourceSelectorWidgetHandler::ConsumeAttribute(FileResourceSelectorWidget* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName)
|
||||
{
|
||||
Q_UNUSED(GUI);
|
||||
Q_UNUSED(attrib);
|
||||
Q_UNUSED(attrValue);
|
||||
Q_UNUSED(debugName);
|
||||
}
|
||||
|
||||
void FileResourceSelectorWidgetHandler::WriteGUIValuesIntoProperty(size_t index, FileResourceSelectorWidget* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_UNUSED(node);
|
||||
CReflectedVarResource val = instance;
|
||||
val.m_propertyType = GUI->GetPropertyType();
|
||||
val.m_path = GUI->GetPath().toUtf8().data();
|
||||
instance = static_cast<property_t>(val);
|
||||
}
|
||||
|
||||
bool FileResourceSelectorWidgetHandler::ReadValuesIntoGUI(size_t index, FileResourceSelectorWidget* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_UNUSED(node);
|
||||
CReflectedVarResource val = instance;
|
||||
GUI->SetPropertyType(val.m_propertyType);
|
||||
GUI->SetPath(val.m_path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
#include <Controls/ReflectedPropertyControl/moc_PropertyResourceCtrl.cpp>
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_UTILS_PROPERTYRESOURCECTRL_H
|
||||
#define CRYINCLUDE_EDITOR_UTILS_PROPERTYRESOURCECTRL_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include "ReflectedVar.h"
|
||||
#include "Util/VariablePropertyType.h"
|
||||
#include <QWidget>
|
||||
#include <QtWidgets/QToolButton>
|
||||
#include <QtCore/QVector>
|
||||
#endif
|
||||
|
||||
class QLineEdit;
|
||||
class QHBoxLayout;
|
||||
class CBitmapToolTip;
|
||||
class QToolTipWidget;
|
||||
|
||||
class BrowseButton
|
||||
: public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BrowseButton, AZ::SystemAllocator, 0);
|
||||
|
||||
BrowseButton(PropertyType type, QWidget* parent = nullptr);
|
||||
|
||||
void SetPath(const QString& path) { m_path = path; }
|
||||
QString GetPath() const { return m_path; }
|
||||
|
||||
PropertyType GetPropertyType() const {return m_propertyType; }
|
||||
|
||||
signals:
|
||||
void PathChanged(const QString& path);
|
||||
|
||||
protected:
|
||||
void SetPathAndEmit(const QString& path);
|
||||
virtual void OnClicked() = 0;
|
||||
|
||||
PropertyType m_propertyType;
|
||||
QString m_path;
|
||||
};
|
||||
|
||||
class FileResourceSelectorWidget
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FileResourceSelectorWidget, AZ::SystemAllocator, 0);
|
||||
FileResourceSelectorWidget(QWidget* pParent = nullptr);
|
||||
|
||||
bool SetPath(const QString& path);
|
||||
QString GetPath() const;
|
||||
void SetPropertyType(PropertyType type);
|
||||
PropertyType GetPropertyType() const { return m_propertyType; }
|
||||
|
||||
QWidget* GetFirstInTabOrder();
|
||||
QWidget* GetLastInTabOrder();
|
||||
void UpdateTabOrder();
|
||||
|
||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
|
||||
signals:
|
||||
void PathChanged(const QString& path);
|
||||
|
||||
protected:
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
private:
|
||||
void OnAssignClicked();
|
||||
void OnMaterialClicked();
|
||||
|
||||
void UpdateWidgets();
|
||||
void AddButton(BrowseButton* button);
|
||||
void OnPathChanged(const QString& path);
|
||||
|
||||
private:
|
||||
QLineEdit* m_pathEdit;
|
||||
PropertyType m_propertyType;
|
||||
QString m_path;
|
||||
|
||||
QHBoxLayout* m_mainLayout;
|
||||
QVector<BrowseButton*> m_buttons;
|
||||
QScopedPointer<CBitmapToolTip> m_previewToolTip;
|
||||
QToolTipWidget* m_tooltip;
|
||||
};
|
||||
|
||||
class FileResourceSelectorWidgetHandler
|
||||
: QObject
|
||||
, public AzToolsFramework::PropertyHandler < CReflectedVarResource, FileResourceSelectorWidget >
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FileResourceSelectorWidgetHandler, AZ::SystemAllocator, 0);
|
||||
|
||||
virtual AZ::u32 GetHandlerName(void) const override { return AZ_CRC("Resource", 0xbc91f416); }
|
||||
virtual bool IsDefaultHandler() const override { return true; }
|
||||
virtual QWidget* GetFirstInTabOrder(FileResourceSelectorWidget* widget) override { return widget->GetFirstInTabOrder(); }
|
||||
virtual QWidget* GetLastInTabOrder(FileResourceSelectorWidget* widget) override { return widget->GetLastInTabOrder(); }
|
||||
virtual void UpdateWidgetInternalTabbing(FileResourceSelectorWidget* widget) override { widget->UpdateTabOrder(); }
|
||||
|
||||
virtual QWidget* CreateGUI(QWidget* pParent) override;
|
||||
virtual void ConsumeAttribute(FileResourceSelectorWidget* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override;
|
||||
virtual void WriteGUIValuesIntoProperty(size_t index, FileResourceSelectorWidget* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
virtual bool ReadValuesIntoGUI(size_t index, FileResourceSelectorWidget* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_UTILS_PROPERTYRESOURCECTRL_H
|
||||
@@ -229,28 +229,16 @@ void ReflectedPropertyItem::SetVariable(IVariable *var)
|
||||
break;
|
||||
case ePropertyFloat:
|
||||
case ePropertyAngle:
|
||||
//if the Description has a valid global enumDB lookup, edit as an enum, otherwise use normal float editor
|
||||
if (desc.m_pEnumDBItem)
|
||||
m_reflectedVarAdapter = new ReflectedVarDBEnumAdapter;
|
||||
else
|
||||
m_reflectedVarAdapter = new ReflectedVarFloatAdapter;
|
||||
m_reflectedVarAdapter = new ReflectedVarFloatAdapter;
|
||||
break;
|
||||
case ePropertyInt:
|
||||
//if the Description has a valid global enumDB lookup, edit as an enum, otherwise use normal int editor
|
||||
if (desc.m_pEnumDBItem)
|
||||
m_reflectedVarAdapter = new ReflectedVarDBEnumAdapter;
|
||||
else
|
||||
m_reflectedVarAdapter = new ReflectedVarIntAdapter;
|
||||
m_reflectedVarAdapter = new ReflectedVarIntAdapter;
|
||||
break;
|
||||
case ePropertyBool:
|
||||
m_reflectedVarAdapter = new ReflectedVarBoolAdapter;
|
||||
break;
|
||||
case ePropertyString:
|
||||
//if the Description has a valid global enumDB lookup, edit as an enum, otherwise use normal string editor
|
||||
if (desc.m_pEnumDBItem)
|
||||
m_reflectedVarAdapter = new ReflectedVarDBEnumAdapter;
|
||||
else
|
||||
m_reflectedVarAdapter = new ReflectedVarStringAdapter;
|
||||
m_reflectedVarAdapter = new ReflectedVarStringAdapter;
|
||||
break;
|
||||
case ePropertySelection:
|
||||
m_reflectedVarAdapter = new ReflectedVarEnumAdapter;
|
||||
|
||||
@@ -70,12 +70,6 @@ void ReflectedVarInit::setupReflection(AZ::SerializeContext* serializeContext)
|
||||
AZ::EditContext* ec = serializeContext->GetEditContext();
|
||||
if (ec)
|
||||
{
|
||||
ec->Class< CReflectedVarResource >("VarResource", "Resource")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &CReflectedVarResource::varName)
|
||||
->Attribute(AZ::Edit::Attributes::DescriptionTextOverride, &CReflectedVarResource::description)
|
||||
;
|
||||
|
||||
ec->Class< CReflectedVarUser >("VarUser", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, &CReflectedVarUser::varName)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
// Editor
|
||||
#include "ReflectedPropertyCtrl.h"
|
||||
#include "UIEnumsDatabase.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -254,41 +253,6 @@ void ReflectedVarEnumAdapter::OnVariableChange([[maybe_unused]] IVariable* pVari
|
||||
}
|
||||
}
|
||||
|
||||
void ReflectedVarDBEnumAdapter::SetVariable(IVariable *pVariable)
|
||||
{
|
||||
Prop::Description desc(pVariable);
|
||||
m_pEnumDBItem = desc.m_pEnumDBItem;
|
||||
m_reflectedVar.reset(new CReflectedVarEnum<AZStd::string>(pVariable->GetHumanName().toUtf8().data()));
|
||||
if (m_pEnumDBItem)
|
||||
{
|
||||
for (int i = 0; i < m_pEnumDBItem->strings.size(); i++)
|
||||
{
|
||||
QString name = m_pEnumDBItem->strings[i];
|
||||
m_reflectedVar->addEnum( m_pEnumDBItem->NameToValue(name).toUtf8().data(), name.toUtf8().data() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReflectedVarDBEnumAdapter::SyncReflectedVarToIVar(IVariable *pVariable)
|
||||
{
|
||||
const AZStd::string valueStr = pVariable->GetDisplayValue().toUtf8().data();
|
||||
const AZStd::string value = m_pEnumDBItem ? AZStd::string(m_pEnumDBItem->ValueToName(valueStr.c_str()).toUtf8().data()) : valueStr;
|
||||
m_reflectedVar->setEnumByName(value);
|
||||
|
||||
}
|
||||
|
||||
void ReflectedVarDBEnumAdapter::SyncIVarToReflectedVar(IVariable *pVariable)
|
||||
{
|
||||
QString iVarVal = m_reflectedVar->m_selectedEnumName.c_str();
|
||||
if (m_pEnumDBItem)
|
||||
{
|
||||
iVarVal = m_pEnumDBItem->NameToValue(iVarVal);
|
||||
}
|
||||
pVariable->SetDisplayValue(iVarVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ReflectedVarVector2Adapter::SetVariable(IVariable *pVariable)
|
||||
{
|
||||
m_reflectedVar.reset(new CReflectedVarVector2(pVariable->GetHumanName().toUtf8().data()));
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <QScopedPointer>
|
||||
|
||||
struct CUIEnumsDatabase_SEnum;
|
||||
class ReflectedPropertyItem;
|
||||
|
||||
// Class to wrap the CReflectedVars and sync them with corresponding IVariable.
|
||||
@@ -145,22 +144,6 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
bool m_updatingEnums;
|
||||
};
|
||||
|
||||
class EDITOR_CORE_API ReflectedVarDBEnumAdapter
|
||||
: public ReflectedVarAdapter
|
||||
{
|
||||
public:
|
||||
void SetVariable(IVariable* pVariable) override;
|
||||
void SyncReflectedVarToIVar(IVariable* pVariable) override;
|
||||
void SyncIVarToReflectedVar(IVariable* pVariable) override;
|
||||
CReflectedVar* GetReflectedVar() override { return m_reflectedVar.data(); }
|
||||
private:
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QScopedPointer<CReflectedVarEnum<AZStd::string> > m_reflectedVar;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
CUIEnumsDatabase_SEnum* m_pEnumDBItem;
|
||||
};
|
||||
|
||||
class EDITOR_CORE_API ReflectedVarVector2Adapter
|
||||
: public ReflectedVarAdapter
|
||||
{
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <QMap>
|
||||
#include <QTranslator>
|
||||
#include <QSet>
|
||||
#include "IEventLoopHook.h"
|
||||
#include <unordered_map>
|
||||
|
||||
#include <AzCore/PlatformDef.h>
|
||||
|
||||
+1
-33
@@ -1709,7 +1709,6 @@ bool CCryEditApp::InitInstance()
|
||||
mainWindow->Initialize();
|
||||
|
||||
GetIEditor()->GetCommandManager()->RegisterAutoCommands();
|
||||
GetIEditor()->AddUIEnums();
|
||||
|
||||
mainWindowWrapper->enableSaveRestoreGeometry("O3DE", "O3DE", "mainWindowGeometry");
|
||||
m_pDocManager->OnFileNew();
|
||||
@@ -1820,10 +1819,7 @@ bool CCryEditApp::InitInstance()
|
||||
if (GetIEditor()->GetCommandManager()->IsRegistered("editor.open_lnm_editor"))
|
||||
{
|
||||
CCommand0::SUIInfo uiInfo;
|
||||
#if !defined(NDEBUG)
|
||||
bool ok =
|
||||
#endif
|
||||
GetIEditor()->GetCommandManager()->GetUIInfo("editor.open_lnm_editor", uiInfo);
|
||||
[[maybe_unused]] bool ok = GetIEditor()->GetCommandManager()->GetUIInfo("editor.open_lnm_editor", uiInfo);
|
||||
assert(ok);
|
||||
}
|
||||
|
||||
@@ -1832,34 +1828,6 @@ bool CCryEditApp::InitInstance()
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCryEditApp::RegisterEventLoopHook(IEventLoopHook* pHook)
|
||||
{
|
||||
pHook->pNextHook = m_pEventLoopHook;
|
||||
m_pEventLoopHook = pHook;
|
||||
}
|
||||
|
||||
void CCryEditApp::UnregisterEventLoopHook(IEventLoopHook* pHookToRemove)
|
||||
{
|
||||
IEventLoopHook* pPrevious = nullptr;
|
||||
for (IEventLoopHook* pHook = m_pEventLoopHook; pHook != nullptr; pHook = pHook->pNextHook)
|
||||
{
|
||||
if (pHook == pHookToRemove)
|
||||
{
|
||||
if (pPrevious)
|
||||
{
|
||||
pPrevious->pNextHook = pHookToRemove->pNextHook;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pEventLoopHook = pHookToRemove->pNextHook;
|
||||
}
|
||||
|
||||
pHookToRemove->pNextHook = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCryEditApp::LoadFile(QString fileName)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,6 @@ class CConsoleDialog;
|
||||
struct mg_connection;
|
||||
struct mg_request_info;
|
||||
struct mg_context;
|
||||
struct IEventLoopHook;
|
||||
class QAction;
|
||||
class MainWindow;
|
||||
class QSharedMemory;
|
||||
@@ -153,8 +152,6 @@ public:
|
||||
int IdleProcessing(bool bBackground);
|
||||
bool IsWindowInForeground();
|
||||
void RunInitPythonScript(CEditCommandLineInfo& cmdInfo);
|
||||
void RegisterEventLoopHook(IEventLoopHook* pHook);
|
||||
void UnregisterEventLoopHook(IEventLoopHook* pHook);
|
||||
|
||||
void DisableIdleProcessing() override;
|
||||
void EnableIdleProcessing() override;
|
||||
@@ -344,7 +341,6 @@ private:
|
||||
|
||||
QString m_lastOpenLevelPath;
|
||||
CQuickAccessBar* m_pQuickAccessBar = nullptr;
|
||||
IEventLoopHook* m_pEventLoopHook = nullptr;
|
||||
QString m_rootEnginePath;
|
||||
|
||||
int m_disableIdleProcessingCounter = 0; //!< Counts requests to disable idle processing. When non-zero, idle processing will be disabled.
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
|
||||
// LmbrCentral
|
||||
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
|
||||
#include <LmbrCentral/Rendering/EditorLightComponentBus.h> // for LmbrCentral::EditorLightComponentRequestBus
|
||||
|
||||
static const char* kAutoBackupFolder = "_autobackup";
|
||||
static const char* kHoldFolder = "$tmp_hold"; // conform to the ignored file types $tmp[0-9]*_ regex
|
||||
@@ -2130,52 +2129,13 @@ void CCryEditDoc::ReleaseXmlArchiveArray(TDocMultiArchive& arrXmlAr)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AzToolsFramework::EditorEntityContextNotificationBus interface implementation
|
||||
void CCryEditDoc::OnSliceInstantiated(const AZ::Data::AssetId& sliceAssetId, AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& /*ticket*/)
|
||||
void CCryEditDoc::OnSliceInstantiated([[maybe_unused]] const AZ::Data::AssetId& sliceAssetId, [[maybe_unused]] AZ::SliceComponent::SliceInstanceAddress& sliceAddress, [[maybe_unused]] const AzFramework::SliceInstantiationTicket& ticket)
|
||||
{
|
||||
if (m_envProbeSliceAssetId == sliceAssetId)
|
||||
{
|
||||
const AZ::SliceComponent::EntityList& entities = sliceAddress.GetInstance()->GetInstantiated()->m_entities;
|
||||
const AZ::Uuid editorEnvProbeComponentId("{8DBD6035-583E-409F-AFD9-F36829A0655D}");
|
||||
AzToolsFramework::EntityIdList entityIds;
|
||||
entityIds.reserve(entities.size());
|
||||
for (const AZ::Entity* entity : entities)
|
||||
{
|
||||
if (entity->FindComponent(editorEnvProbeComponentId))
|
||||
{
|
||||
// Update Probe Area size to cover the whole terrain
|
||||
LmbrCentral::EditorLightComponentRequestBus::Event(entity->GetId(), &LmbrCentral::EditorLightComponentRequests::SetProbeAreaDimensions, AZ::Vector3(m_terrainSize, m_terrainSize, m_envProbeHeight));
|
||||
|
||||
// Force update the light to apply cubemap
|
||||
LmbrCentral::EditorLightComponentRequestBus::Event(entity->GetId(), &LmbrCentral::EditorLightComponentRequests::RefreshLight);
|
||||
}
|
||||
entityIds.push_back(entity->GetId());
|
||||
}
|
||||
|
||||
//Detach instantiated env probe entities from engine slice
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceRequestBus::Broadcast(
|
||||
&AzToolsFramework::SliceEditorEntityOwnershipServiceRequests::DetachSliceEntities, entityIds);
|
||||
|
||||
sliceAddress.SetInstance(nullptr);
|
||||
sliceAddress.SetReference(nullptr);
|
||||
SetModifiedFlag(true);
|
||||
SetModifiedModules(eModifiedEntities);
|
||||
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
//save after level default slice fully instantiated
|
||||
Save();
|
||||
}
|
||||
GetIEditor()->ResumeUndo();
|
||||
}
|
||||
|
||||
|
||||
void CCryEditDoc::OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId, const AzFramework::SliceInstantiationTicket& /*ticket*/)
|
||||
void CCryEditDoc::OnSliceInstantiationFailed([[maybe_unused]] const AZ::Data::AssetId& sliceAssetId, [[maybe_unused]] const AzFramework::SliceInstantiationTicket& ticket)
|
||||
{
|
||||
if (m_envProbeSliceAssetId == sliceAssetId)
|
||||
{
|
||||
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusDisconnect();
|
||||
AZ_Warning("Editor", false, "Failed to instantiate default environment probe slice.");
|
||||
}
|
||||
GetIEditor()->ResumeUndo();
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user