Merge branch 'development' of https://github.com/o3de/o3de into TerrainMaterialsFix
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6d6204c6730e5675791765ca194e9b1cbec282208e280507de830afc2805e5fa
|
||||
size 41127
|
||||
oid sha256:de0e6e480ece5b423222f4feacf56553d73713fe9afea8bbc9a2660a3cd54ec7
|
||||
size 1232
|
||||
|
||||
@@ -87,12 +87,18 @@ class AtomComponentProperties:
|
||||
def decal(property: str = 'name') -> str:
|
||||
"""
|
||||
Decal component properties.
|
||||
- 'Attenuation Angle' controls how much the angle between geometry and decal impacts opacity. 0-1 Radians
|
||||
- 'Opacity' where one is opaque and zero is transparent
|
||||
- 'Sort Key' 0-255 stacking z-sort like key to define which decal is on top of another
|
||||
- 'Material' the material Asset.id of the decal.
|
||||
: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': 'Decal',
|
||||
'Attenuation Angle': 'Controller|Configuration|Attenuation Angle',
|
||||
'Opacity': 'Controller|Configuration|Opacity',
|
||||
'Sort Key': 'Controller|Configuration|Sort Key',
|
||||
'Material': 'Controller|Configuration|Material',
|
||||
}
|
||||
return properties[property]
|
||||
@@ -242,12 +248,14 @@ class AtomComponentProperties:
|
||||
def grid(property: str = 'name') -> str:
|
||||
"""
|
||||
Grid component properties.
|
||||
- 'Grid Size': The size of the grid, default value is 32
|
||||
- 'Secondary Grid Spacing': The spacing value for the secondary grid, i.e. 1.0
|
||||
: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': 'Grid',
|
||||
'Grid Size': 'Controller|Configuration|Grid Size',
|
||||
'Secondary Grid Spacing': 'Controller|Configuration|Secondary Grid Spacing',
|
||||
}
|
||||
return properties[property]
|
||||
@@ -378,11 +386,13 @@ class AtomComponentProperties:
|
||||
def physical_sky(property: str = 'name') -> str:
|
||||
"""
|
||||
Physical Sky component properties.
|
||||
- 'Sky Intensity' float that determines sky intensity value, default value is 4.
|
||||
: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': 'Physical Sky',
|
||||
'Sky Intensity': 'Controller|Configuration|Sky Intensity',
|
||||
}
|
||||
return properties[property]
|
||||
|
||||
|
||||
@@ -114,11 +114,11 @@ def get_property(document_id, property_name):
|
||||
"""
|
||||
:return: property value or invalid value if the document is not open or the property_name can't be found
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentRequestBus(bus.Event, "GetPropertyValue", document_id, property_name)
|
||||
return azlmbr.materialeditor.MaterialDocumentRequestBus(bus.Event, "GetPropertyValue", document_id, property_name)
|
||||
|
||||
|
||||
def set_property(document_id, property_name, value):
|
||||
azlmbr.atomtools.AtomToolsDocumentRequestBus(bus.Event, "SetPropertyValue", document_id, property_name, value)
|
||||
azlmbr.materialeditor.MaterialDocumentRequestBus(bus.Event, "SetPropertyValue", document_id, property_name, value)
|
||||
|
||||
|
||||
def is_pane_visible(pane_name):
|
||||
|
||||
+86
-43
@@ -8,49 +8,61 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
class Tests:
|
||||
camera_creation = (
|
||||
"Camera Entity successfully created",
|
||||
"Camera Entity failed to be created")
|
||||
"P0: Camera Entity failed to be created")
|
||||
camera_component_added = (
|
||||
"Camera component was added to entity",
|
||||
"Camera component failed to be added to entity")
|
||||
"P0: Camera component failed to be added to entity")
|
||||
camera_component_check = (
|
||||
"Entity has a Camera component",
|
||||
"Entity failed to find Camera component")
|
||||
"P0: Entity failed to find Camera component")
|
||||
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")
|
||||
decal_creation = (
|
||||
"Decal Entity successfully created",
|
||||
"Decal Entity failed to be created")
|
||||
"P0: Decal Entity failed to be created")
|
||||
decal_component = (
|
||||
"Entity has a Decal component",
|
||||
"Entity failed to find Decal component")
|
||||
"P0: Entity failed to find Decal component")
|
||||
decal_component_removed = (
|
||||
"Decal component removed",
|
||||
"P0: Decal component failed to be removed")
|
||||
material_property_set = (
|
||||
"Material property set on Decal component",
|
||||
"Couldn't set Material property on Decal component")
|
||||
"P0: Couldn't set Material property on Decal component")
|
||||
attenuation_property_set = (
|
||||
"Attenuation Angle property set on Decal component",
|
||||
"P1: Couldn't set Attenuation Angle property on Decal component")
|
||||
opacity_property_set = (
|
||||
"Opacity property set on Decal component",
|
||||
"P1: Coudn't set Opacity property on Decal component")
|
||||
sort_key_property_set = (
|
||||
"Sort Key property set on Decal component",
|
||||
"P1: Couldn't set Sort Key property on Decal 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")
|
||||
|
||||
|
||||
def AtomEditorComponents_Decal_AddedToEntity():
|
||||
@@ -71,14 +83,18 @@ def AtomEditorComponents_Decal_AddedToEntity():
|
||||
2) Add Decal component to Decal 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) Set Material property on Decal component.
|
||||
9) Delete Decal entity.
|
||||
10) UNDO deletion.
|
||||
11) REDO deletion.
|
||||
12) Look for errors and asserts.
|
||||
5) Set Material property on Decal component.
|
||||
6) Set Attenuation Angle property on Decal component.
|
||||
7) Set Opacity property on Decal component
|
||||
8) Set Sort Key property on Decal Component
|
||||
9) Remove Decal component then UNDO the remove
|
||||
10) Enter/Exit game mode.
|
||||
11) Test IsHidden.
|
||||
12) Test IsVisible.
|
||||
13) Delete Decal entity.
|
||||
14) UNDO deletion.
|
||||
15) REDO deletion.
|
||||
16) Look for errors and asserts.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
@@ -130,42 +146,69 @@ def AtomEditorComponents_Decal_AddedToEntity():
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, decal_entity.exists())
|
||||
|
||||
# 5. 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.
|
||||
decal_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, decal_entity.is_hidden() is True)
|
||||
|
||||
# 7. Test IsVisible.
|
||||
decal_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, decal_entity.is_visible() is True)
|
||||
|
||||
# 8. Set Material property on Decal component.
|
||||
decal_material_asset_path = os.path.join("materials", "basic_grey.azmaterial")
|
||||
# 5. Set Material property on Decal component.
|
||||
decal_material_asset_path = os.path.join("materials", "decal", "airship_symbol_decal.azmaterial")
|
||||
decal_material_asset = Asset.find_asset_by_path(decal_material_asset_path, False)
|
||||
decal_component.set_component_property_value(AtomComponentProperties.decal('Material'), decal_material_asset.id)
|
||||
get_material_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Material'))
|
||||
Report.result(Tests.material_property_set, get_material_property == decal_material_asset.id)
|
||||
|
||||
# 9. Delete Decal entity.
|
||||
# 6. Set Attenuation Angle property on Decal component
|
||||
decal_component.set_component_property_value(AtomComponentProperties.decal('Attenuation Angle'), value=0.75)
|
||||
get_attenuation_property = decal_component.get_component_property_value(
|
||||
AtomComponentProperties.decal('Attenuation Angle'))
|
||||
Report.result(Tests.attenuation_property_set, get_attenuation_property == 0.75)
|
||||
|
||||
# 7. Set Opacity property on Decal component
|
||||
decal_component.set_component_property_value(AtomComponentProperties.decal('Opacity'), value=0.5)
|
||||
get_opacity_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Opacity'))
|
||||
Report.result(Tests.opacity_property_set, get_opacity_property == 0.5)
|
||||
|
||||
# 8. Set Sort Key property on Decal component
|
||||
decal_component.set_component_property_value(AtomComponentProperties.decal('Sort Key'), value=255.0)
|
||||
get_sort_key_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Sort Key'))
|
||||
Report.result(Tests.sort_key_property_set, get_sort_key_property == 255.0)
|
||||
decal_component.set_component_property_value(AtomComponentProperties.decal('Sort Key'), value=0)
|
||||
get_sort_key_property = decal_component.get_component_property_value(AtomComponentProperties.decal('Sort Key'))
|
||||
Report.result(Tests.sort_key_property_set, get_sort_key_property == 0)
|
||||
|
||||
# 9. Remove Decal component then UNDO the remove
|
||||
decal_component.remove()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.decal_component_removed, not decal_entity.has_component(AtomComponentProperties.decal()))
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.decal_component, decal_entity.has_component(AtomComponentProperties.decal()))
|
||||
|
||||
# 10. 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)
|
||||
|
||||
# 11. Test IsHidden.
|
||||
decal_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, decal_entity.is_hidden() is True)
|
||||
|
||||
# 12. Test IsVisible.
|
||||
decal_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, decal_entity.is_visible() is True)
|
||||
|
||||
# 13. Delete Decal entity.
|
||||
decal_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not decal_entity.exists())
|
||||
|
||||
# 10. UNDO deletion.
|
||||
# 14. UNDO deletion.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_undo, decal_entity.exists())
|
||||
|
||||
# 11. REDO deletion.
|
||||
# 15. REDO deletion.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_redo, not decal_entity.exists())
|
||||
|
||||
# 12. Look for errors and asserts.
|
||||
# 16. 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}")
|
||||
|
||||
+25
-14
@@ -18,6 +18,9 @@ class Tests:
|
||||
grid_component_added = (
|
||||
"Entity has a Grid component",
|
||||
"Entity failed to find Grid component")
|
||||
grid_size = (
|
||||
"Grid Size value set successfully",
|
||||
"Grid Size value could not be set")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
@@ -59,13 +62,14 @@ def AtomEditorComponents_Grid_AddedToEntity():
|
||||
2) Add a Grid component to Grid 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 Grid entity.
|
||||
9) UNDO deletion.
|
||||
10) REDO deletion.
|
||||
11) Look for errors.
|
||||
5) Grid Size changed.
|
||||
6) Enter/Exit game mode.
|
||||
7) Test IsHidden.
|
||||
8) Test IsVisible.
|
||||
9) Delete Grid entity.
|
||||
10) UNDO deletion.
|
||||
11) REDO deletion.
|
||||
12) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
@@ -119,35 +123,42 @@ def AtomEditorComponents_Grid_AddedToEntity():
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, grid_entity.exists())
|
||||
|
||||
# 5. Enter/Exit game mode.
|
||||
# 5. Grid Size changed
|
||||
grid_component.set_component_property_value(
|
||||
AtomComponentProperties.grid('Grid Size'), value=64)
|
||||
current_grid_size = grid_component.get_component_property_value(
|
||||
AtomComponentProperties.grid('Grid Size'))
|
||||
Report.result(Tests.grid_size, current_grid_size == 64)
|
||||
|
||||
# 6. 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.
|
||||
# 7. Test IsHidden.
|
||||
grid_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, grid_entity.is_hidden() is True)
|
||||
|
||||
# 7. Test IsVisible.
|
||||
# 8. Test IsVisible.
|
||||
grid_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, grid_entity.is_visible() is True)
|
||||
|
||||
# 8. Delete Grid entity.
|
||||
# 9. Delete Grid entity.
|
||||
grid_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not grid_entity.exists())
|
||||
|
||||
# 9. UNDO deletion.
|
||||
# 10. UNDO deletion.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_undo, grid_entity.exists())
|
||||
|
||||
# 10. REDO deletion.
|
||||
# 11. REDO deletion.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_redo, not grid_entity.exists())
|
||||
|
||||
# 11. Look for errors or asserts.
|
||||
# 12. 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}")
|
||||
|
||||
+27
-15
@@ -68,13 +68,14 @@ def AtomEditorComponents_Light_AddedToEntity():
|
||||
2) Add Light component to the Light 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 Light entity.
|
||||
9) UNDO deletion.
|
||||
10) REDO deletion.
|
||||
11) Look for errors.
|
||||
5) Cycle through all light types.
|
||||
6) Enter/Exit game mode.
|
||||
7) Test IsHidden.
|
||||
8) Test IsVisible.
|
||||
9) Delete Light entity.
|
||||
10) UNDO deletion.
|
||||
11) REDO deletion.
|
||||
12) Look for errors.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
@@ -83,7 +84,7 @@ def AtomEditorComponents_Light_AddedToEntity():
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import Report, Tracer, TestHelper
|
||||
from Atom.atom_utils.atom_constants import AtomComponentProperties
|
||||
from Atom.atom_utils.atom_constants import AtomComponentProperties, LIGHT_TYPES
|
||||
|
||||
with Tracer() as error_tracer:
|
||||
# Test setup begins.
|
||||
@@ -124,35 +125,46 @@ def AtomEditorComponents_Light_AddedToEntity():
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, light_entity.exists())
|
||||
|
||||
# 5. Enter/Exit game mode.
|
||||
# 5. Cycle through all light types.
|
||||
for light_type in LIGHT_TYPES.keys():
|
||||
light_component.set_component_property_value(
|
||||
AtomComponentProperties.light('Light type'), LIGHT_TYPES[light_type])
|
||||
current_light_type = light_component.get_component_property_value(
|
||||
AtomComponentProperties.light('Light type'))
|
||||
test_light_type = (
|
||||
f"Light component has {light_type} type set",
|
||||
f"Light component failed to set {light_type} type")
|
||||
Report.result(test_light_type, current_light_type == LIGHT_TYPES[light_type])
|
||||
|
||||
# 6. 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.
|
||||
# 7. Test IsHidden.
|
||||
light_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, light_entity.is_hidden() is True)
|
||||
|
||||
# 7. Test IsVisible.
|
||||
# 8. Test IsVisible.
|
||||
light_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, light_entity.is_visible() is True)
|
||||
|
||||
# 8. Delete Light entity.
|
||||
# 9. Delete Light entity.
|
||||
light_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not light_entity.exists())
|
||||
|
||||
# 9. UNDO deletion.
|
||||
# 10. UNDO deletion.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_undo, light_entity.exists())
|
||||
|
||||
# 10. REDO deletion.
|
||||
# 11. REDO deletion.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_redo, not light_entity.exists())
|
||||
|
||||
# 11. Look for errors asserts.
|
||||
# 12. Look for errors 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}")
|
||||
|
||||
+25
-14
@@ -27,6 +27,9 @@ class Tests:
|
||||
physical_sky_component = (
|
||||
"Entity has a Physical Sky component",
|
||||
"Entity failed to find Physical Sky component")
|
||||
sky_intensity = (
|
||||
"Sky Intensity value updated successfully",
|
||||
"Sky Intensity value could not be set")
|
||||
enter_game_mode = (
|
||||
"Entered game mode",
|
||||
"Failed to enter game mode")
|
||||
@@ -68,13 +71,14 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
|
||||
2) Add Physical Sky component to Physical Sky 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 Physical Sky entity.
|
||||
9) UNDO deletion.
|
||||
10) REDO deletion.
|
||||
11) Look for errors and asserts.
|
||||
5) Update Sky Intensity value.
|
||||
6) Enter/Exit game mode.
|
||||
7) Test IsHidden.
|
||||
8) Test IsVisible.
|
||||
9) Delete Physical Sky entity.
|
||||
10) UNDO deletion.
|
||||
11) REDO deletion.
|
||||
12) Look for errors and asserts.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
@@ -126,35 +130,42 @@ def AtomEditorComponents_PhysicalSky_AddedToEntity():
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.creation_redo, physical_sky_entity.exists())
|
||||
|
||||
# 5. Enter/Exit game mode.
|
||||
# 5. Set Sky Intensity value
|
||||
physical_sky_component.set_component_property_value(
|
||||
AtomComponentProperties.physical_sky('Sky Intensity'), value=2)
|
||||
current_sky_intensity = physical_sky_component.get_component_property_value(
|
||||
AtomComponentProperties.physical_sky('Sky Intensity'))
|
||||
Report.result(Tests.sky_intensity, current_sky_intensity == 2)
|
||||
|
||||
# 6. 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.
|
||||
# 7. Test IsHidden.
|
||||
physical_sky_entity.set_visibility_state(False)
|
||||
Report.result(Tests.is_hidden, physical_sky_entity.is_hidden() is True)
|
||||
|
||||
# 7. Test IsVisible.
|
||||
# 8. Test IsVisible.
|
||||
physical_sky_entity.set_visibility_state(True)
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.is_visible, physical_sky_entity.is_visible() is True)
|
||||
|
||||
# 8. Delete Physical Sky entity.
|
||||
# 9. Delete Physical Sky entity.
|
||||
physical_sky_entity.delete()
|
||||
Report.result(Tests.entity_deleted, not physical_sky_entity.exists())
|
||||
|
||||
# 9. UNDO deletion.
|
||||
# 10. UNDO deletion.
|
||||
general.undo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_undo, physical_sky_entity.exists())
|
||||
|
||||
# 10. REDO deletion.
|
||||
# 11. REDO deletion.
|
||||
general.redo()
|
||||
general.idle_wait_frames(1)
|
||||
Report.result(Tests.deletion_redo, not physical_sky_entity.exists())
|
||||
|
||||
# 11. Look for errors and asserts.
|
||||
# 12. 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}")
|
||||
|
||||
+8
@@ -34,6 +34,7 @@ class EditorComponent:
|
||||
EditorEntity.add_component() or Entity.add_components() or EditorEntity.get_components_of_type()
|
||||
which also assigns self.id and self.type_id to the EditorComponent object.
|
||||
self.type_id is the UUID for the component type as provided by an ebus call.
|
||||
self.id is an azlmbr.entity.EntityComponentIdPair which contains both entity and component id's
|
||||
"""
|
||||
|
||||
def __init__(self, type_id: uuid):
|
||||
@@ -270,6 +271,13 @@ class EditorComponent:
|
||||
warnings.warn("disable_component is deprecated, use set_enabled(False) instead.", DeprecationWarning)
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [self.id])
|
||||
|
||||
def remove(self):
|
||||
"""
|
||||
Removes the component from its associated entity. Essentially a delete since only UNDO can return it.
|
||||
:return: None
|
||||
"""
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", [self.id])
|
||||
|
||||
@staticmethod
|
||||
def get_type_ids(component_names: list, entity_type: EditorEntityType = EditorEntityType.GAME) -> list:
|
||||
"""
|
||||
|
||||
@@ -31,11 +31,15 @@ class TestAutomation(TestAutomationBase):
|
||||
def test_Multiplayer_AutoComponent_NetworkInput(self, request, workspace, editor, launcher_platform):
|
||||
from .tests import Multiplayer_AutoComponent_NetworkInput as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
|
||||
|
||||
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_BasicConnectivity_Connects(self, request, workspace, editor, launcher_platform):
|
||||
from .tests import Multiplayer_BasicConnectivity_Connects 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)
|
||||
|
||||
+20
-6
@@ -62,17 +62,31 @@ 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)
|
||||
|
||||
# Autonomous->Authority RPC
|
||||
# Sending 2 RPCs: 1 containing a parameter and 1 without
|
||||
AUTONOMOUS_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS = 1.0 # This RPC is sent as soon as the autonomous player script is spawned. 1 second should be more than enough time to send/receive that RPC.
|
||||
helper.succeed_if_log_line_found('Script', "AutoComponent_RPC: Sending AutonomousToAuthorityNoParam RPC.", section_tracer.prints, AUTONOMOUS_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS)
|
||||
helper.succeed_if_log_line_found('Script', "AutoComponent_RPC: Sending AutonomousToAuthority RPC (with float param).", section_tracer.prints, AUTONOMOUS_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS)
|
||||
helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC: Successfully received AutonomousToAuthorityNoParams RPC.", section_tracer.prints, AUTONOMOUS_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS)
|
||||
helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC: Successfully received AutonomousToAuthority RPC (with expected float param).", section_tracer.prints, AUTONOMOUS_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS)
|
||||
|
||||
# Server->Authority RPC. Inter-Entity Communication.
|
||||
SERVER_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS = 1.0 # This RPC is sent as soon as the networked level entity finds the player in the level, and previous tests are relying on the player's existence. 1 second should be more than enough time to send/receive that RPC.
|
||||
helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC_NetLevelEntity: Send ServerToAuthority RPC.", section_tracer.prints, SERVER_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS)
|
||||
helper.succeed_if_log_line_found('EditorServer', "Script: AutoComponent_RPC: Received ServerToAuthority RPC. Damage=42.", section_tracer.prints, SERVER_TO_AUTHORITY_RPC_WAIT_TIME_SECONDS)
|
||||
|
||||
|
||||
|
||||
# Exit game mode
|
||||
helper.exit_game_mode(TestSuccessFailTuples.exit_game_mode)
|
||||
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
"""
|
||||
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 the basic client connect test works
|
||||
|
||||
|
||||
# fmt: off
|
||||
class TestConstants:
|
||||
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_BasicConnectivity_Connects():
|
||||
r"""
|
||||
Summary:
|
||||
Runs a test to make sure that a networked player can be spawned
|
||||
|
||||
Level Description:
|
||||
- Dynamic
|
||||
1. Although the level is empty, when the server and editor connect the server will spawn the player prefab.
|
||||
- Static
|
||||
1. This is an empty level.
|
||||
|
||||
Expected Outcome:
|
||||
We should see the player connect and spawn with no errors.
|
||||
|
||||
: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
|
||||
|
||||
|
||||
level_name = "BasicConnectivity_Connects"
|
||||
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(TestConstants.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(TestConstants.find_network_player, player_id.IsValid())
|
||||
|
||||
# Exit game mode
|
||||
helper.exit_game_mode(TestConstants.exit_game_mode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Multiplayer_BasicConnectivity_Connects)
|
||||
+6
-12
@@ -4,6 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
class HeightTests:
|
||||
single_gradient_height_correct = (
|
||||
"Successfully retrieved height for gradient1.",
|
||||
@@ -22,6 +23,7 @@ class HeightTests:
|
||||
"OnTerrainDataChanged call count incorrect."
|
||||
)
|
||||
|
||||
|
||||
def TerrainHeightGradientList_AddRemoveGradientWorks():
|
||||
"""
|
||||
Summary:
|
||||
@@ -29,22 +31,16 @@ def TerrainHeightGradientList_AddRemoveGradientWorks():
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
import math as sys_math
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.math as math
|
||||
import azlmbr.terrain as terrain
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.vegetation as vegetation
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
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
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
|
||||
terrain_changed_call_count = 0
|
||||
expected_terrain_changed_calls = 0
|
||||
@@ -87,11 +83,8 @@ def TerrainHeightGradientList_AddRemoveGradientWorks():
|
||||
|
||||
Report.result(test_results, sys_math.isclose(height, expected_height, abs_tol=test_tolerance))
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# Open a level.
|
||||
helper.open_level("Physics", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
hydra.open_base_level()
|
||||
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
@@ -101,7 +94,7 @@ def TerrainHeightGradientList_AddRemoveGradientWorks():
|
||||
aabb_height = 1024.0
|
||||
box_dimensions = math.Vector3(1.0, 1.0, aabb_height);
|
||||
|
||||
# Create a main entity with a LayerSpawner, AAbb and HeightGradientList.
|
||||
# Create a main entity with a LayerSpawner, AAbb and HeightGradientList.
|
||||
main_entity = create_entity_at("entity2", [layerspawner_component_name, gradientlist_component_name, aabb_component_name], 0.0, 0.0, aabb_height/2.0)
|
||||
|
||||
# Create three gradient entities.
|
||||
@@ -138,7 +131,8 @@ def TerrainHeightGradientList_AddRemoveGradientWorks():
|
||||
# Add gradient3, the height should still be the second value, as that was the highest.
|
||||
set_gradients_check_height(main_entity, [gradient_entity1.id, gradient_entity2.id, gradient_entity3.id], aabb_height * gradient_values[1], HeightTests.triple_gradient_height_correct)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(TerrainHeightGradientList_AddRemoveGradientWorks)
|
||||
Report.start_test(TerrainHeightGradientList_AddRemoveGradientWorks)
|
||||
|
||||
+5
-10
@@ -4,6 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
class MacroMaterialTests:
|
||||
setup_test = (
|
||||
"Setup successful",
|
||||
@@ -30,6 +31,7 @@ class MacroMaterialTests:
|
||||
"Timed out waiting for OnTerrainMacroMaterialRegionChanged"
|
||||
)
|
||||
|
||||
|
||||
def TerrainMacroMaterialComponent_MacroMaterialActivates():
|
||||
"""
|
||||
Summary:
|
||||
@@ -38,7 +40,6 @@ def TerrainMacroMaterialComponent_MacroMaterialActivates():
|
||||
"""
|
||||
|
||||
import os
|
||||
import math as sys_math
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.asset as asset
|
||||
@@ -46,15 +47,11 @@ def TerrainMacroMaterialComponent_MacroMaterialActivates():
|
||||
import azlmbr.math as math
|
||||
import azlmbr.terrain as terrain
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.vegetation as vegetation
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
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
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.asset_utils import Asset
|
||||
|
||||
material_created_called = False
|
||||
material_changed_called = False
|
||||
@@ -84,11 +81,8 @@ def TerrainMacroMaterialComponent_MacroMaterialActivates():
|
||||
nonlocal material_destroyed_called
|
||||
material_destroyed_called = True
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# Open a level.
|
||||
helper.open_level("Physics", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
hydra.open_base_level()
|
||||
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
@@ -160,7 +154,8 @@ def TerrainMacroMaterialComponent_MacroMaterialActivates():
|
||||
region_changed_call_result = helper.wait_for_condition(lambda: material_region_changed_called == True, 2.0)
|
||||
Report.result(MacroMaterialTests.material_changed_call_on_aabb_change, region_changed_call_result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(TerrainMacroMaterialComponent_MacroMaterialActivates)
|
||||
Report.start_test(TerrainMacroMaterialComponent_MacroMaterialActivates)
|
||||
|
||||
+7
-5
@@ -5,8 +5,9 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
#fmt: off
|
||||
class Tests():
|
||||
class Tests:
|
||||
create_test_entity = ("Entity created successfully", "Failed to create Entity")
|
||||
add_axis_aligned_box_shape = ("Axis Aligned Box Shape component added", "Failed to add Axis Aligned Box Shape component")
|
||||
add_terrain_collider = ("Terrain Physics Heightfield Collider component added", "Failed to add a Terrain Physics Heightfield Collider component")
|
||||
@@ -14,6 +15,7 @@ class Tests():
|
||||
configuration_changed = ("Terrain size changed successfully", "Failed terrain size change")
|
||||
#fmt: on
|
||||
|
||||
|
||||
def TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges():
|
||||
"""
|
||||
Summary:
|
||||
@@ -36,24 +38,24 @@ def TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges():
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
from editor_python_test_tools.utils import Report, Tracer
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
import azlmbr.physics as physics
|
||||
import azlmbr.math as azmath
|
||||
import azlmbr.bus as bus
|
||||
import sys
|
||||
|
||||
import math
|
||||
|
||||
SET_BOX_X_SIZE = 5.0
|
||||
SET_BOX_Y_SIZE = 6.0
|
||||
EXPECTED_COLUMN_SIZE = SET_BOX_X_SIZE + 1
|
||||
EXPECTED_ROW_SIZE = SET_BOX_Y_SIZE + 1
|
||||
helper.init_idle()
|
||||
|
||||
# 1) Load the level
|
||||
helper.open_level("", "Base")
|
||||
hydra.open_base_level()
|
||||
|
||||
# 2) Create test entity
|
||||
test_entity = EditorEntity.create_editor_entity("TestEntity")
|
||||
|
||||
+3
-8
@@ -54,7 +54,6 @@ def TerrainSystem_VegetationSpawnsOnTerrainSurfaces():
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import math as sys_math
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
@@ -62,10 +61,8 @@ def TerrainSystem_VegetationSpawnsOnTerrainSurfaces():
|
||||
import azlmbr.math as math
|
||||
|
||||
import azlmbr.areasystem as areasystem
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.vegetation as vegetation
|
||||
import azlmbr.terrain as terrain
|
||||
import azlmbr.entity as EntityId
|
||||
import azlmbr.surface_data as surface_data
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
@@ -86,11 +83,8 @@ def TerrainSystem_VegetationSpawnsOnTerrainSurfaces():
|
||||
|
||||
return highest_z, lowest_z
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
# Open an empty level.
|
||||
helper.open_level("Physics", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
hydra.open_base_level()
|
||||
|
||||
general.idle_wait_frames(1)
|
||||
|
||||
@@ -208,7 +202,8 @@ def TerrainSystem_VegetationSpawnsOnTerrainSurfaces():
|
||||
|
||||
Report.result(VegetationTests.testTag3_excluded_vegetation_z_correct, highest_z < box_height * gradient_value_2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(TerrainSystem_VegetationSpawnsOnTerrainSurfaces)
|
||||
Report.start_test(TerrainSystem_VegetationSpawnsOnTerrainSurfaces)
|
||||
|
||||
@@ -5,8 +5,9 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
|
||||
#fmt: off
|
||||
class Tests():
|
||||
class Tests:
|
||||
create_terrain_spawner_entity = ("Terrain_spawner_entity created successfully", "Failed to create terrain_spawner_entity")
|
||||
create_height_provider_entity = ("Height_provider_entity created successfully", "Failed to create height_provider_entity")
|
||||
create_test_ball = ("Ball created successfully", "Failed to create Ball")
|
||||
@@ -19,6 +20,7 @@ class Tests():
|
||||
no_errors_and_warnings_found = ("No errors and warnings found", "Found errors and warnings")
|
||||
#fmt: on
|
||||
|
||||
|
||||
def Terrain_SupportsPhysics():
|
||||
"""
|
||||
Summary:
|
||||
@@ -46,8 +48,7 @@ def Terrain_SupportsPhysics():
|
||||
:return: None
|
||||
"""
|
||||
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import TestHelper as helper, Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
from editor_python_test_tools.utils import Report, Tracer
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
import azlmbr.math as azmath
|
||||
@@ -59,12 +60,9 @@ def Terrain_SupportsPhysics():
|
||||
SET_BOX_X_SIZE = 1024.0
|
||||
SET_BOX_Y_SIZE = 1024.0
|
||||
SET_BOX_Z_SIZE = 100.0
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
|
||||
# 1) Load the level
|
||||
helper.open_level("", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
hydra.open_base_level()
|
||||
|
||||
#1a) Load the level components
|
||||
hydra.add_level_component("Terrain World")
|
||||
|
||||
+6
-10
@@ -47,8 +47,8 @@ def Terrain_World_ConfigurationWorks():
|
||||
12) Check terrain does not exist at a known position outside the world
|
||||
13) Check height value is the expected one when query resolution is changed
|
||||
"""
|
||||
from editor_python_test_tools.editor_entity_utils import EditorEntity
|
||||
from editor_python_test_tools.utils import TestHelper as helper, Report
|
||||
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
from editor_python_test_tools.utils import Report, Tracer
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
import azlmbr.math as azmath
|
||||
@@ -62,14 +62,11 @@ def Terrain_World_ConfigurationWorks():
|
||||
SET_BOX_Y_SIZE = 2048.0
|
||||
SET_BOX_Z_SIZE = 100.0
|
||||
CLAMP = 1
|
||||
|
||||
helper.init_idle()
|
||||
|
||||
|
||||
# 1) Start the Tracer to catch any errors and warnings
|
||||
with Tracer() as section_tracer:
|
||||
# 2) Load the level
|
||||
helper.open_level("", "Base")
|
||||
helper.wait_for_condition(lambda: general.get_current_level_name() == "Base", 2.0)
|
||||
hydra.open_base_level()
|
||||
|
||||
# 3) Load the level components
|
||||
terrain_world_component = hydra.add_level_component("Terrain World")
|
||||
@@ -93,7 +90,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 +145,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 +162,3 @@ if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Terrain_World_ConfigurationWorks)
|
||||
|
||||
|
||||
@@ -3,25 +3,18 @@ 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
|
||||
|
||||
"""
|
||||
|
||||
# This suite consists of all test cases that are passing and have been verified.
|
||||
|
||||
import pytest
|
||||
import os
|
||||
import sys
|
||||
|
||||
from ly_test_tools import LAUNCHERS
|
||||
from ly_test_tools.o3de.editor_test import EditorTestSuite, EditorSharedTest
|
||||
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
enable_prefab_system = False
|
||||
|
||||
class test_AxisAlignedBoxShape_ConfigurationWorks(EditorSharedTest):
|
||||
from .EditorScripts import TerrainPhysicsCollider_ChangesSizeWithAxisAlignedBoxShapeChanges as test_module
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ class TestAutomationBase:
|
||||
file_system.restore_backup(workspace.paths.editor_log(), workspace.paths.project_log())
|
||||
except FileNotFoundError as e:
|
||||
self.logger.debug(f"File restoration failed, editor log could not be found.\nError: {e}")
|
||||
editor.kill()
|
||||
editor.stop()
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
@@ -113,7 +113,7 @@ class TestAutomationBase:
|
||||
editor.wait(TestAutomationBase.MAX_TIMEOUT)
|
||||
except WaitTimeoutError:
|
||||
errors.append(TestRunError("TIMEOUT", f"Editor did not close after {TestAutomationBase.MAX_TIMEOUT} seconds, verify the test is ending and the application didn't freeze"))
|
||||
editor.kill()
|
||||
editor.stop()
|
||||
|
||||
output = editor.get_output()
|
||||
self.logger.debug("Test output:\n" + output)
|
||||
|
||||
@@ -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
|
||||
@@ -681,23 +669,17 @@
|
||||
"Component_[7256163899440301540]": {
|
||||
"$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"
|
||||
}
|
||||
},
|
||||
"m_name": "AutoComponent_RPC_NetLevelEntity.scriptcanvas",
|
||||
"runtimeDataIsValid": true,
|
||||
"runtimeDataOverrides": {
|
||||
"source": {
|
||||
"assetId": {
|
||||
"guid": "{1D517006-AC01-5ECA-AE66-0E007871F0CD}"
|
||||
},
|
||||
"assetHint": "levels/multiplayer/autocomponent_rpc/autocomponent_rpc_netlevelentity.scriptcanvas"
|
||||
"id": "{1D517006-AC01-5ECA-AE66-0E007871F0CD}",
|
||||
"path": "C:/prj/o3de/AutomatedTesting/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 +712,6 @@
|
||||
"$type": "NetBindComponent"
|
||||
}
|
||||
},
|
||||
"Component_[9816897251206708579]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 9816897251206708579,
|
||||
"m_template": {
|
||||
"$type": "AutomatedTesting::NetworkTestPlayerComponent"
|
||||
}
|
||||
},
|
||||
"Component_[9880860858035405475]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 9880860858035405475
|
||||
|
||||
+196662
-100
File diff suppressed because it is too large
Load Diff
+2614
-54
File diff suppressed because it is too large
Load Diff
@@ -91,22 +91,10 @@
|
||||
"$type": "EditorScriptCanvasComponent",
|
||||
"Id": 10596595655489113153,
|
||||
"m_name": "AutoComponent_RPC",
|
||||
"m_assetHolder": {
|
||||
"m_asset": {
|
||||
"assetId": {
|
||||
"guid": "{5ED120C4-07DC-56F1-80A7-37BFC98FD74E}"
|
||||
},
|
||||
"assetHint": "levels/multiplayer/autocomponent_rpc/autocomponent_rpc.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"runtimeDataIsValid": true,
|
||||
"runtimeDataOverrides": {
|
||||
"source": {
|
||||
"assetId": {
|
||||
"guid": "{5ED120C4-07DC-56F1-80A7-37BFC98FD74E}"
|
||||
},
|
||||
"assetHint": "levels/multiplayer/autocomponent_rpc/autocomponent_rpc.scriptcanvas"
|
||||
}
|
||||
"sourceHandle": {
|
||||
"id": "{5ED120C4-07DC-56F1-80A7-37BFC98FD74E}",
|
||||
"path": "levels/multiplayer/autocomponent_rpc/autocomponent_rpc.scriptcanvas"
|
||||
}
|
||||
},
|
||||
"Component_[11440172471478606933]": {
|
||||
@@ -184,6 +172,13 @@
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 9407892837096707905
|
||||
},
|
||||
"Component_[9505416969829669337]": {
|
||||
"$type": "EditorTagComponent",
|
||||
"Id": 9505416969829669337,
|
||||
"Tags": [
|
||||
"Player"
|
||||
]
|
||||
},
|
||||
"Component_[9878555871810913249]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 9878555871810913249,
|
||||
|
||||
+581
@@ -0,0 +1,581 @@
|
||||
{
|
||||
"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
|
||||
},
|
||||
"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": 8929576024571800510
|
||||
}
|
||||
}
|
||||
},
|
||||
"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_[1172344194419]": {
|
||||
"Id": "Entity_[1172344194419]",
|
||||
"Name": "Shader Ball",
|
||||
"Components": {
|
||||
"Component_[10789351944715265527]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 10789351944715265527
|
||||
},
|
||||
"Component_[12037033284781049225]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 12037033284781049225
|
||||
},
|
||||
"Component_[13759153306105970079]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 13759153306105970079
|
||||
},
|
||||
"Component_[14135560884830586279]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14135560884830586279
|
||||
},
|
||||
"Component_[16247165675903986673]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 16247165675903986673
|
||||
},
|
||||
"Component_[18082433625958885247]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 18082433625958885247
|
||||
},
|
||||
"Component_[6472623349872972660]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 6472623349872972660,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Transform Data": {
|
||||
"Rotate": [
|
||||
0.0,
|
||||
0.10000000149011612,
|
||||
180.0
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[6495255223970673916]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 6495255223970673916,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
|
||||
"subId": 281415304
|
||||
},
|
||||
"assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[8056625192494070973]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 8056625192494070973
|
||||
},
|
||||
"Component_[8550141614185782969]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 8550141614185782969
|
||||
},
|
||||
"Component_[9439770997198325425]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 9439770997198325425
|
||||
}
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"ChildEntityOrderEntryArray": [
|
||||
{
|
||||
"EntityId": "Entity_[1155164325235]"
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1180934129011]",
|
||||
"SortIndex": 1
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1172344194419]",
|
||||
"SortIndex": 2
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1168049227123]",
|
||||
"SortIndex": 3
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1163754259827]",
|
||||
"SortIndex": 4
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1159459292531]",
|
||||
"SortIndex": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Instances": {
|
||||
"Instance_[450137905015]": {
|
||||
"Source": "Levels/Multiplayer/BasicConnectivity_Connects/Player.prefab",
|
||||
"Patches": [
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/ContainerEntity/Components/Component_[14438229160106431107]/Parent Entity",
|
||||
"value": "../Entity_[1146574390643]"
|
||||
},
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/ContainerEntity/Components/Component_[14438229160106431107]/Transform Data/Translate/1",
|
||||
"value": 10.0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"ContainerEntity": {
|
||||
"Id": "ContainerEntity",
|
||||
"Name": "Player",
|
||||
"Components": {
|
||||
"Component_[10518577910351346732]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 10518577910351346732
|
||||
},
|
||||
"Component_[10982887273490848966]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 10982887273490848966
|
||||
},
|
||||
"Component_[12400551793021799684]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 12400551793021799684
|
||||
},
|
||||
"Component_[1257365873906714292]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 1257365873906714292
|
||||
},
|
||||
"Component_[13311663931994949767]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 13311663931994949767
|
||||
},
|
||||
"Component_[14438229160106431107]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 14438229160106431107,
|
||||
"Parent Entity": ""
|
||||
},
|
||||
"Component_[14636573223251575153]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 14636573223251575153
|
||||
},
|
||||
"Component_[18139850826775373128]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 18139850826775373128
|
||||
},
|
||||
"Component_[18149872971727933150]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 18149872971727933150
|
||||
},
|
||||
"Component_[3361461948531668955]": {
|
||||
"$type": "EditorPrefabComponent",
|
||||
"Id": 3361461948531668955
|
||||
},
|
||||
"Component_[5198421115432838729]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 5198421115432838729
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entities": {
|
||||
"Entity_[458727839607]": {
|
||||
"Id": "Entity_[458727839607]",
|
||||
"Name": "Dummy",
|
||||
"Components": {
|
||||
"Component_[10453091667729858383]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 10453091667729858383
|
||||
},
|
||||
"Component_[15287888392848689630]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 15287888392848689630
|
||||
},
|
||||
"Component_[15410933204460181490]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 15410933204460181490,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 868882495636022739
|
||||
},
|
||||
{
|
||||
"ComponentId": 517239536919559179,
|
||||
"SortIndex": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[17682830444684716936]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 17682830444684716936
|
||||
},
|
||||
"Component_[18433579260689698157]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 18433579260689698157
|
||||
},
|
||||
"Component_[2684999590909523769]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 2684999590909523769
|
||||
},
|
||||
"Component_[517239536919559179]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 517239536919559179,
|
||||
"m_template": {
|
||||
"$type": "NetBindComponent"
|
||||
}
|
||||
},
|
||||
"Component_[5980561685482761342]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5980561685482761342
|
||||
},
|
||||
"Component_[6553553408068929590]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 6553553408068929590
|
||||
},
|
||||
"Component_[8307469961954670365]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 8307469961954670365
|
||||
},
|
||||
"Component_[868882495636022739]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 868882495636022739,
|
||||
"Parent Entity": "ContainerEntity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"materialType": "Materials/Types/StandardPBR.materialtype",
|
||||
"materialTypeVersion": 4,
|
||||
"properties": {
|
||||
"baseColor": {
|
||||
"textureMap": "Materials/decal/airship_symbol_decal.tif"
|
||||
},
|
||||
"general": {
|
||||
"doubleSided": true
|
||||
},
|
||||
"metallic": {
|
||||
"useTexture": false
|
||||
},
|
||||
"normal": {
|
||||
"useTexture": false
|
||||
},
|
||||
"opacity": {
|
||||
"alphaSource": "Split",
|
||||
"factor": 0.6899999976158142,
|
||||
"mode": "Cutout",
|
||||
"textureMap": "Materials/decal/airship_symbol_decal.tif"
|
||||
},
|
||||
"roughness": {
|
||||
"useTexture": false
|
||||
},
|
||||
"specularF0": {
|
||||
"useTexture": false
|
||||
},
|
||||
"uv": {
|
||||
"center": [
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2252ba28e19432d99e58fa03b672f855e1f520805eda71764e076fe349e1915a
|
||||
size 4205906
|
||||
@@ -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": [
|
||||
|
||||
@@ -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,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__
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -588,7 +588,7 @@ QMenu* LevelEditorMenuHandler::CreateGameMenu()
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
// Export to Engine
|
||||
|
||||
@@ -706,7 +706,7 @@ void CCryEditApp::OnFileSave()
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
@@ -2364,7 +2364,7 @@ void CCryEditApp::ExportLevel(bool bExportToGame, bool bExportTexture, bool bAut
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Prefab system doesn't require level exports.");
|
||||
@@ -2405,7 +2405,7 @@ bool CCryEditApp::UserExportToGame(bool bNoMsgBox)
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Export Level should no longer exist.");
|
||||
@@ -2453,7 +2453,7 @@ void CCryEditApp::ExportToGame(bool bNoMsgBox)
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Prefab system no longer exports levels.");
|
||||
@@ -2961,7 +2961,7 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
// If we are creating a new level and we're in simulate mode, then switch it off before we do anything else
|
||||
if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode())
|
||||
@@ -3107,7 +3107,7 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled)
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
QString str = QObject::tr("Level %1 has been changed. Save Level?").arg(GetIEditor()->GetGameEngine()->GetLevelName());
|
||||
@@ -3321,7 +3321,7 @@ CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* filename, bool addToMostR
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
// If we are loading and we're in simulate mode, then switch it off before we do anything else
|
||||
if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode())
|
||||
|
||||
@@ -371,7 +371,7 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
@@ -636,7 +636,7 @@ bool CCryEditDoc::SaveModified()
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
QMessageBox saveModifiedMessageBox(AzToolsFramework::GetActiveWindow());
|
||||
@@ -699,7 +699,7 @@ void CCryEditDoc::OnFileSaveAs()
|
||||
CCryEditApp::instance()->AddToRecentFileList(levelFileDialog.GetFileName());
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId =
|
||||
@@ -728,7 +728,7 @@ bool CCryEditDoc::BeforeOpenDocument(const QString& lpszPathName, TOpenDocContex
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
|
||||
@@ -101,7 +101,7 @@ void CEditorPreferencesPage_AWS::SaveSettingsRegistryFile()
|
||||
return;
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool saved{};
|
||||
[[maybe_unused]] bool saved = false;
|
||||
constexpr auto configurationMode =
|
||||
AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY;
|
||||
if (AZ::IO::SystemFile outputFile; outputFile.Open(resolvedPath.data(), configurationMode))
|
||||
|
||||
@@ -586,6 +586,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
|
||||
break;
|
||||
|
||||
case eNotify_OnEndLoad:
|
||||
case eNotify_OnEndCreate:
|
||||
UpdateScene();
|
||||
SetDefaultCamera();
|
||||
break;
|
||||
|
||||
@@ -489,7 +489,7 @@ bool CGameEngine::LoadLevel(
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
|
||||
@@ -100,7 +100,7 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
@@ -317,8 +317,8 @@ void CGameExporter::ExportLevelInfo(const QString& path)
|
||||
root->setAttr("Name", levelName.toUtf8().data());
|
||||
auto terrain = AzFramework::Terrain::TerrainDataRequestBus::FindFirstHandler();
|
||||
const AZ::Aabb terrainAabb = terrain ? terrain->GetTerrainAabb() : AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero());
|
||||
const AZ::Vector2 terrainGridResolution = terrain ? terrain->GetTerrainHeightQueryResolution() : AZ::Vector2::CreateOne();
|
||||
const int compiledHeightmapSize = static_cast<int>(terrainAabb.GetXExtent() / terrainGridResolution.GetX());
|
||||
const float terrainGridResolution = terrain ? terrain->GetTerrainHeightQueryResolution() : 1.0f;
|
||||
const int compiledHeightmapSize = static_cast<int>(terrainAabb.GetXExtent() / terrainGridResolution);
|
||||
root->setAttr("HeightmapSize", compiledHeightmapSize);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -70,7 +70,7 @@ private:
|
||||
{
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
AZ_Assert(false, "Level.pak should no longer be used when prefabs are used for levels.");
|
||||
|
||||
@@ -659,7 +659,7 @@ void MainWindow::InitActions()
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (!usePrefabSystemForLevels)
|
||||
{
|
||||
am->AddAction(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE, tr("&Export to Engine"))
|
||||
|
||||
@@ -499,14 +499,12 @@ void CEntityObject::AdjustLightProperties(CVarBlockPtr& properties, const char*
|
||||
pAreaLight->SetHumanName("PlanarLight");
|
||||
}
|
||||
|
||||
bool bCastShadowLegacy = false; // Backward compatibility for existing shadow casting lights
|
||||
if (IVariable* pCastShadowVarLegacy = FindVariableInSubBlock(properties, pSubBlockVar, "bCastShadow"))
|
||||
{
|
||||
pCastShadowVarLegacy->SetFlags(pCastShadowVarLegacy->GetFlags() | IVariable::UI_INVISIBLE);
|
||||
const QString zeroPrefix("0");
|
||||
if (!pCastShadowVarLegacy->GetDisplayValue().startsWith(zeroPrefix))
|
||||
{
|
||||
bCastShadowLegacy = true;
|
||||
pCastShadowVarLegacy->SetDisplayValue(zeroPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,7 +1084,7 @@ void SEditorSettings::SaveSettingsRegistryFile()
|
||||
return;
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool saved{};
|
||||
[[maybe_unused]] bool saved = false;
|
||||
constexpr auto configurationMode = AZ::IO::SystemFile::SF_OPEN_CREATE
|
||||
| AZ::IO::SystemFile::SF_OPEN_CREATE_PATH
|
||||
| AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY;
|
||||
|
||||
@@ -22,13 +22,6 @@ set(FILES
|
||||
Controls/ReflectedPropertyControl/ReflectedVar.h
|
||||
Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp
|
||||
Controls/ReflectedPropertyControl/ReflectedVarWrapper.h
|
||||
Controls/QBitmapPreviewDialog.cpp
|
||||
Controls/QBitmapPreviewDialog.h
|
||||
Controls/QBitmapPreviewDialog.ui
|
||||
Controls/QBitmapPreviewDialogImp.cpp
|
||||
Controls/QBitmapPreviewDialogImp.h
|
||||
Controls/QToolTipWidget.h
|
||||
Controls/QToolTipWidget.cpp
|
||||
UsedResources.cpp
|
||||
LyViewPaneNames.h
|
||||
QtViewPaneManager.cpp
|
||||
|
||||
@@ -313,8 +313,6 @@ set(FILES
|
||||
AssetEditor/AssetEditorWindow.ui
|
||||
Commands/CommandManager.cpp
|
||||
Commands/CommandManager.h
|
||||
Controls/BitmapToolTip.cpp
|
||||
Controls/BitmapToolTip.h
|
||||
Controls/ConsoleSCB.cpp
|
||||
Controls/ConsoleSCB.h
|
||||
Controls/ConsoleSCB.ui
|
||||
@@ -336,8 +334,6 @@ set(FILES
|
||||
Controls/ReflectedPropertyControl/PropertyMiscCtrl.h
|
||||
Controls/ReflectedPropertyControl/PropertyMotionCtrl.cpp
|
||||
Controls/ReflectedPropertyControl/PropertyMotionCtrl.h
|
||||
Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp
|
||||
Controls/ReflectedPropertyControl/PropertyResourceCtrl.h
|
||||
Controls/ReflectedPropertyControl/PropertyCtrl.cpp
|
||||
Controls/ReflectedPropertyControl/PropertyCtrl.h
|
||||
MainStatusBar.cpp
|
||||
|
||||
@@ -36,5 +36,12 @@ namespace AZStd
|
||||
{
|
||||
pthread_setname_np(tId, name);
|
||||
}
|
||||
|
||||
uint8_t GetDefaultThreadPriority()
|
||||
{
|
||||
// pthread priority is an integer between >=1 and <=99 (although only range 1<=>32 is guaranteed)
|
||||
// Don't use a scheduling policy value (e.g. SCHED_OTHER or SCHED_FIFO) here.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-1
@@ -35,7 +35,7 @@ namespace AZStd
|
||||
|
||||
void SetThreadPriority(int priority, pthread_attr_t& attr)
|
||||
{
|
||||
if (priority == -1)
|
||||
if (priority <= -1)
|
||||
{
|
||||
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
|
||||
}
|
||||
@@ -59,5 +59,18 @@ namespace AZStd
|
||||
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)& policyData, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Apple pthread -> NSThread quality of service level map
|
||||
// QOS class name | min pthread priority | max pthread priority | comment
|
||||
// QOS_CLASS_USER_INTERACTIVE | 38 | 47 | Per-frame work
|
||||
// QOS_CLASS_USER_INITIATED | 32 | 37 | Asynchronous / Cross frame work
|
||||
// QOS_CLASS_DEFAULT | 21 | 31 | Streaming / Multiple frames deadline
|
||||
// QOS_CLASS_UTILITY | 5 | 20 | Background asset download
|
||||
// QOS_CLASS_BACKGROUN | 0 | 4 | Will be prevented from using whole core.
|
||||
uint8_t GetDefaultThreadPriority()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -21,6 +21,7 @@ namespace AZStd
|
||||
void PreCreateSetThreadAffinity(int cpuId, pthread_attr_t& attr);
|
||||
void SetThreadPriority(int priority, pthread_attr_t& attr);
|
||||
void PostCreateThread(pthread_t tId, const char * name, int cpuId);
|
||||
uint8_t GetDefaultThreadPriority();
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
@@ -60,12 +61,13 @@ namespace AZStd
|
||||
}
|
||||
else
|
||||
{
|
||||
priority = SCHED_OTHER;
|
||||
priority = Platform::GetDefaultThreadPriority();
|
||||
}
|
||||
if (desc->m_name)
|
||||
{
|
||||
name = desc->m_name;
|
||||
}
|
||||
ti->m_name = name;
|
||||
cpuId = desc->m_cpuId;
|
||||
|
||||
pthread_attr_setdetachstate(&attr, desc->m_isJoinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED);
|
||||
|
||||
@@ -55,5 +55,12 @@ namespace AZStd
|
||||
{
|
||||
pthread_setname_np(tId, name);
|
||||
}
|
||||
|
||||
uint8_t GetDefaultThreadPriority()
|
||||
{
|
||||
// pthread priority is an integer between >=1 and <=99 (although only range 1<=>32 is guaranteed)
|
||||
// Don't use a scheduling policy value (e.g. SCHED_OTHER or SCHED_FIFO) here.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,13 +447,13 @@ namespace UnitTest
|
||||
{
|
||||
x -= 1;
|
||||
});
|
||||
|
||||
// a <-- Root
|
||||
// / \
|
||||
// b c
|
||||
// \ /
|
||||
// d
|
||||
|
||||
/*
|
||||
a <-- Root
|
||||
/ \
|
||||
b c
|
||||
\ /
|
||||
d
|
||||
*/
|
||||
a.Precedes(b, c);
|
||||
d.Follows(b, c);
|
||||
|
||||
@@ -522,20 +522,20 @@ namespace UnitTest
|
||||
{
|
||||
x -= 1;
|
||||
});
|
||||
|
||||
// NOTE: The ideal way to express this topology is without the wait on the subgraph
|
||||
// at task g, but this is more an illustrative test. Better is to express the entire
|
||||
// graph in a single larger graph.
|
||||
// a <-- Root
|
||||
// / \
|
||||
// b c - f
|
||||
// \ \ \
|
||||
// \ e - g
|
||||
// \ /
|
||||
// \ /
|
||||
// \ /
|
||||
// d
|
||||
|
||||
/*
|
||||
NOTE: The ideal way to express this topology is without the wait on the subgraph
|
||||
at task g, but this is more an illustrative test. Better is to express the entire
|
||||
graph in a single larger graph.
|
||||
a <-- Root
|
||||
/ \
|
||||
b c - f
|
||||
\ \ \
|
||||
\ e - g
|
||||
\ /
|
||||
\ /
|
||||
\ /
|
||||
d
|
||||
*/
|
||||
a.Precedes(b);
|
||||
a.Precedes(c);
|
||||
b.Precedes(d);
|
||||
@@ -593,17 +593,17 @@ namespace UnitTest
|
||||
{
|
||||
x += 0b1000;
|
||||
});
|
||||
|
||||
// a <-- Root
|
||||
// / \
|
||||
// b c - f
|
||||
// \ \ \
|
||||
// \ e - g
|
||||
// \ /
|
||||
// \ /
|
||||
// \ /
|
||||
// d
|
||||
|
||||
/*
|
||||
a <-- Root
|
||||
/ \
|
||||
b c - f
|
||||
\ \ \
|
||||
\ e - g
|
||||
\ /
|
||||
\ /
|
||||
\ /
|
||||
d
|
||||
*/
|
||||
a.Precedes(b, c);
|
||||
b.Precedes(d);
|
||||
c.Precedes(e, f);
|
||||
|
||||
@@ -112,6 +112,7 @@ namespace AzFramework
|
||||
virtual void SetPrefabSystemEnabled([[maybe_unused]] bool enable) {}
|
||||
|
||||
/// Returns true if Prefab System is enabled for use with levels, false if legacy level system is enabled (level.pak)
|
||||
/// @deprecated Use 'IsPrefabSystemEnabled' instead
|
||||
virtual bool IsPrefabSystemForLevelsEnabled() const { return false; }
|
||||
|
||||
/// Returns true if code should assert when the Legacy Slice System is used
|
||||
|
||||
@@ -765,6 +765,7 @@ namespace AzFramework
|
||||
|
||||
bool Application::IsPrefabSystemForLevelsEnabled() const
|
||||
{
|
||||
AZ_Warning("Application", false, "'IsPrefabSystemForLevelsEnabled' is deprecated, please use 'IsPrefabSystemEnabled' instead.");
|
||||
return IsPrefabSystemEnabled();
|
||||
}
|
||||
|
||||
|
||||
@@ -1208,7 +1208,7 @@ namespace AZ::IO
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (usePrefabSystemForLevels)
|
||||
{
|
||||
@@ -1274,7 +1274,7 @@ namespace AZ::IO
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
AZStd::unique_lock lock(m_csZips);
|
||||
for (auto it = m_arrZips.begin(); it != m_arrZips.end();)
|
||||
|
||||
@@ -378,7 +378,7 @@ namespace Physics
|
||||
m_cachedNativeHeightfield = cachedNativeHeightfield;
|
||||
}
|
||||
|
||||
AZ::Vector2 HeightfieldShapeConfiguration::GetGridResolution() const
|
||||
const AZ::Vector2& HeightfieldShapeConfiguration::GetGridResolution() const
|
||||
{
|
||||
return m_gridResolution;
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace Physics
|
||||
const void* GetCachedNativeHeightfield() const;
|
||||
void* GetCachedNativeHeightfield();
|
||||
void SetCachedNativeHeightfield(void* cachedNativeHeightfield);
|
||||
AZ::Vector2 GetGridResolution() const;
|
||||
const AZ::Vector2& GetGridResolution() const;
|
||||
void SetGridResolution(const AZ::Vector2& gridSpacing);
|
||||
int32_t GetNumColumns() const;
|
||||
void SetNumColumns(int32_t numColumns);
|
||||
@@ -235,7 +235,7 @@ namespace Physics
|
||||
void SetMaxHeightBounds(float maxBounds);
|
||||
|
||||
private:
|
||||
//! The number of meters between each heightfield sample.
|
||||
//! The number of meters between each heightfield sample in x and y.
|
||||
AZ::Vector2 m_gridResolution{ 1.0f };
|
||||
//! The number of columns in the heightfield sample grid.
|
||||
int32_t m_numColumns{ 0 };
|
||||
|
||||
@@ -50,8 +50,8 @@ namespace AzFramework
|
||||
static AZ::Vector3 GetDefaultTerrainNormal() { return AZ::Vector3::CreateAxisZ(); }
|
||||
|
||||
// System-level queries to understand world size and resolution
|
||||
virtual AZ::Vector2 GetTerrainHeightQueryResolution() const = 0;
|
||||
virtual void SetTerrainHeightQueryResolution(AZ::Vector2 queryResolution) = 0;
|
||||
virtual float GetTerrainHeightQueryResolution() const = 0;
|
||||
virtual void SetTerrainHeightQueryResolution(float queryResolution) = 0;
|
||||
|
||||
virtual AZ::Aabb GetTerrainAabb() const = 0;
|
||||
virtual void SetTerrainAabb(const AZ::Aabb& worldBounds) = 0;
|
||||
|
||||
@@ -165,10 +165,6 @@ set(FILES
|
||||
Logging/MissingAssetLogger.cpp
|
||||
Logging/MissingAssetLogger.h
|
||||
Logging/MissingAssetNotificationBus.h
|
||||
Matchmaking/IMatchmakingRequests.h
|
||||
Matchmaking/MatchmakingRequests.cpp
|
||||
Matchmaking/MatchmakingRequests.h
|
||||
Matchmaking/MatchmakingNotifications.h
|
||||
Scene/Scene.h
|
||||
Scene/Scene.inl
|
||||
Scene/Scene.cpp
|
||||
@@ -182,13 +178,6 @@ set(FILES
|
||||
Script/ScriptDebugMsgReflection.h
|
||||
Script/ScriptRemoteDebugging.cpp
|
||||
Script/ScriptRemoteDebugging.h
|
||||
Session/ISessionHandlingRequests.h
|
||||
Session/ISessionRequests.h
|
||||
Session/SessionRequests.cpp
|
||||
Session/SessionRequests.h
|
||||
Session/SessionConfig.cpp
|
||||
Session/SessionConfig.h
|
||||
Session/SessionNotifications.h
|
||||
StreamingInstall/StreamingInstall.h
|
||||
StreamingInstall/StreamingInstall.cpp
|
||||
StreamingInstall/StreamingInstallRequests.h
|
||||
|
||||
@@ -49,8 +49,8 @@ namespace UnitTest
|
||||
AzFramework::Terrain::TerrainDataRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
MOCK_CONST_METHOD0(GetTerrainHeightQueryResolution, AZ::Vector2());
|
||||
MOCK_METHOD1(SetTerrainHeightQueryResolution, void(AZ::Vector2));
|
||||
MOCK_CONST_METHOD0(GetTerrainHeightQueryResolution, float());
|
||||
MOCK_METHOD1(SetTerrainHeightQueryResolution, void(float));
|
||||
MOCK_CONST_METHOD0(GetTerrainAabb, AZ::Aabb());
|
||||
MOCK_METHOD1(SetTerrainAabb, void(const AZ::Aabb&));
|
||||
MOCK_CONST_METHOD3(GetHeight, float(const AZ::Vector3&, Sampler, bool*));
|
||||
|
||||
-2
@@ -47,8 +47,6 @@ namespace AzManipulatorTestFramework
|
||||
virtual void UpdateVisibility() = 0;
|
||||
//! Sets if sticky select is enabled or not.
|
||||
virtual void SetStickySelect(bool enabled) = 0;
|
||||
//! Gets default Editor Camera Position.
|
||||
virtual AZ::Vector3 DefaultEditorCameraPosition() const = 0;
|
||||
//! Sets if icons are visible in the viewport.
|
||||
virtual void SetIconsVisible(bool visible) = 0;
|
||||
//! Sets if helpers are visible in the viewport.
|
||||
|
||||
+2
-21
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzFramework/Visibility/EntityVisibilityQuery.h>
|
||||
#include <AzManipulatorTestFramework/AzManipulatorTestFramework.h>
|
||||
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -22,7 +23,7 @@ namespace AzManipulatorTestFramework
|
||||
class ViewportInteraction
|
||||
: public ViewportInteractionInterface
|
||||
, public AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus::Handler
|
||||
, public AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler
|
||||
, public UnitTest::ViewportSettingsTestImpl
|
||||
, private AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
@@ -50,19 +51,6 @@ namespace AzManipulatorTestFramework
|
||||
const AzFramework::ScreenPoint& screenPosition) override;
|
||||
float DeviceScalingFactor() override;
|
||||
|
||||
// ViewportSettingsRequestBus overrides ...
|
||||
bool GridSnappingEnabled() const override;
|
||||
float GridSize() const override;
|
||||
bool ShowGrid() const override;
|
||||
bool AngleSnappingEnabled() const override;
|
||||
float AngleStep() const override;
|
||||
float ManipulatorLineBoundWidth() const override;
|
||||
float ManipulatorCircleBoundWidth() const override;
|
||||
bool StickySelectEnabled() const override;
|
||||
AZ::Vector3 DefaultEditorCameraPosition() const override;
|
||||
bool IconsVisible() const override;
|
||||
bool HelpersVisible() const override;
|
||||
|
||||
// EditorEntityViewportInteractionRequestBus overrides ...
|
||||
void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) override;
|
||||
|
||||
@@ -72,12 +60,5 @@ namespace AzManipulatorTestFramework
|
||||
AzFramework::EntityVisibilityQuery m_entityVisibilityQuery;
|
||||
AZStd::shared_ptr<AzFramework::DebugDisplayRequests> m_debugDisplayRequests;
|
||||
AzFramework::CameraState m_cameraState;
|
||||
float m_gridSize = 1.0f;
|
||||
float m_angularStep = 0.0f;
|
||||
bool m_gridSnapping = false;
|
||||
bool m_angularSnapping = false;
|
||||
bool m_stickySelect = true;
|
||||
bool m_iconsVisible = true;
|
||||
bool m_helpersVisible = true;
|
||||
};
|
||||
} // namespace AzManipulatorTestFramework
|
||||
|
||||
@@ -37,46 +37,6 @@ namespace AzManipulatorTestFramework
|
||||
return m_cameraState;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::GridSnappingEnabled() const
|
||||
{
|
||||
return m_gridSnapping;
|
||||
}
|
||||
|
||||
float ViewportInteraction::GridSize() const
|
||||
{
|
||||
return m_gridSize;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::ShowGrid() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::AngleSnappingEnabled() const
|
||||
{
|
||||
return m_angularSnapping;
|
||||
}
|
||||
|
||||
float ViewportInteraction::AngleStep() const
|
||||
{
|
||||
return m_angularStep;
|
||||
}
|
||||
|
||||
float ViewportInteraction::ManipulatorLineBoundWidth() const
|
||||
{
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
float ViewportInteraction::ManipulatorCircleBoundWidth() const
|
||||
{
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::StickySelectEnabled() const
|
||||
{
|
||||
return m_stickySelect;
|
||||
}
|
||||
|
||||
void ViewportInteraction::FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntitiesOut)
|
||||
{
|
||||
visibleEntitiesOut.assign(m_entityVisibilityQuery.Begin(), m_entityVisibilityQuery.End());
|
||||
@@ -127,11 +87,6 @@ namespace AzManipulatorTestFramework
|
||||
m_helpersVisible = visible;
|
||||
}
|
||||
|
||||
AZ::Vector3 ViewportInteraction::DefaultEditorCameraPosition() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void ViewportInteraction::SetGridSize(float size)
|
||||
{
|
||||
m_gridSize = size;
|
||||
@@ -162,14 +117,4 @@ namespace AzManipulatorTestFramework
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::IconsVisible() const
|
||||
{
|
||||
return m_iconsVisible;
|
||||
}
|
||||
|
||||
bool ViewportInteraction::HelpersVisible() const
|
||||
{
|
||||
return m_helpersVisible;
|
||||
}
|
||||
} // namespace AzManipulatorTestFramework
|
||||
|
||||
+1
-1
@@ -295,7 +295,7 @@ namespace AzToolsFramework
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
|
||||
{
|
||||
|
||||
+42
-18
@@ -19,45 +19,69 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
//! A RootAliasPath can be used to store an alias path that starts from the Prefab EOS root instance.
|
||||
//! The root instance itself is included in the path. These can be used as Instance handles across systems
|
||||
//! that do not have visibility over InstanceOptionalReferences, or that need to store Instance handles
|
||||
//! for longer than just the span of a function without the risk of them going out of scope.
|
||||
using RootAliasPath = AliasPath;
|
||||
}
|
||||
|
||||
class PrefabEditorEntityOwnershipInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(PrefabEditorEntityOwnershipInterface,"{38E764BA-A089-49F3-848F-46018822CE2E}");
|
||||
AZ_RTTI(PrefabEditorEntityOwnershipInterface, "{38E764BA-A089-49F3-848F-46018822CE2E}");
|
||||
|
||||
//! Returns whether the system has a root instance assigned.
|
||||
//! @return True if a root prefab is assigned, false otherwise.
|
||||
virtual bool IsRootPrefabAssigned() const = 0;
|
||||
|
||||
//! Returns an optional reference to the root prefab instance.
|
||||
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
|
||||
|
||||
//! Returns the template id for the root prefab instance.
|
||||
virtual Prefab::TemplateId GetRootPrefabTemplateId() = 0;
|
||||
|
||||
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
|
||||
|
||||
//! Creates a prefab instance with the provided entities and nestedPrefabInstances.
|
||||
//! /param entities The entities to put under the new prefab.
|
||||
//! /param nestedPrefabInstances The nested prefab instances to put under the new prefab.
|
||||
//! /param filePath The filepath corresponding to the prefab file to be created.
|
||||
//! /param instanceToParentUnder The instance the newly created prefab instance is parented under.
|
||||
//! /return The optional reference to the prefab created.
|
||||
//! @param entities The entities to put under the new prefab.
|
||||
//! @param nestedPrefabInstances The nested prefab instances to put under the new prefab.
|
||||
//! @param filePath The filepath corresponding to the prefab file to be created.
|
||||
//! @param instanceToParentUnder The instance the newly created prefab instance is parented under.
|
||||
//! @return The optional reference to the prefab created.
|
||||
virtual Prefab::InstanceOptionalReference CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
|
||||
|
||||
//! Instantiate the prefab file provided.
|
||||
//! /param filePath The filepath for the prefab file the instance should be created from.
|
||||
//! /param instanceToParentUnder The instance the newly instantiated prefab instance is parented under.
|
||||
//! /return The optional reference to the prefab instance.
|
||||
//! @param filePath The filepath for the prefab file the instance should be created from.
|
||||
//! @param instanceToParentUnder The instance the newly instantiated prefab instance is parented under.
|
||||
//! @return The optional reference to the prefab instance.
|
||||
virtual Prefab::InstanceOptionalReference InstantiatePrefab(
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
|
||||
|
||||
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
|
||||
|
||||
virtual Prefab::TemplateId GetRootPrefabTemplateId() = 0;
|
||||
virtual void StartPlayInEditor() = 0;
|
||||
virtual void StopPlayInEditor() = 0;
|
||||
|
||||
//! Get all Assets generated by Prefab processing when entering Play-In Editor mode (Ctrl+G)
|
||||
//! /return The vector of Assets generated by Prefab processing
|
||||
//! @return The vector of Assets generated by Prefab processing
|
||||
virtual const Prefab::PrefabConversionUtils::InMemorySpawnableAssetContainer::SpawnableAssets& GetPlayInEditorAssetData() const = 0;
|
||||
|
||||
virtual bool LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
|
||||
virtual bool SaveToStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
|
||||
|
||||
virtual void StartPlayInEditor() = 0;
|
||||
virtual void StopPlayInEditor() = 0;
|
||||
|
||||
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
|
||||
//! Returns the reference to the instance corresponding to the RootAliasPath provided.
|
||||
//! @param rootAliasPath The RootAliasPath to be queried.
|
||||
//! @return A reference to the instance if valid, AZStd::nullopt otherwise.
|
||||
virtual Prefab::InstanceOptionalReference GetInstanceReferenceFromRootAliasPath(Prefab::RootAliasPath rootAliasPath) const = 0;
|
||||
|
||||
virtual bool IsRootPrefabAssigned() const = 0;
|
||||
//! Allows to iterate through all instances referenced in the path, from the root down.
|
||||
//! @param rootAliasPath The RootAliasPath to iterate through. If invalid, callback will not be called.
|
||||
//! @param callback The function to call on each instance. If it returns true, it prevents the rest of the path from being called.
|
||||
//! @return True if the iteration was halted by a callback returning true, false otherwise. Also returns false if the path is invalid.
|
||||
virtual bool GetInstancesInRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
+64
@@ -510,6 +510,70 @@ namespace AzToolsFramework
|
||||
m_playInEditorData.m_isEnabled = false;
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::IsValidRootAliasPath(Prefab::RootAliasPath rootAliasPath) const
|
||||
{
|
||||
return GetInstanceReferenceFromRootAliasPath(rootAliasPath) != AZStd::nullopt;
|
||||
}
|
||||
|
||||
Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::GetInstanceReferenceFromRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath) const
|
||||
{
|
||||
Prefab::InstanceOptionalReference instance = *m_rootInstance;
|
||||
|
||||
for (const auto& pathElement : rootAliasPath)
|
||||
{
|
||||
if (pathElement.Native() == rootAliasPath.begin()->Native())
|
||||
{
|
||||
// If the root is not the root Instance, the rootAliasPath is invalid.
|
||||
if (pathElement.Native() != instance->get().GetInstanceAlias())
|
||||
{
|
||||
return Prefab::InstanceOptionalReference();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the instance alias can't be found, the rootAliasPath is invalid.
|
||||
instance = instance->get().FindNestedInstance(pathElement.Native());
|
||||
if (!instance.has_value())
|
||||
{
|
||||
return Prefab::InstanceOptionalReference();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::GetInstancesInRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const
|
||||
{
|
||||
if (!IsValidRootAliasPath(rootAliasPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Prefab::InstanceOptionalReference instance;
|
||||
|
||||
for (const auto& pathElement : rootAliasPath)
|
||||
{
|
||||
if (!instance.has_value())
|
||||
{
|
||||
instance = *m_rootInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = instance->get().FindNestedInstance(pathElement.Native());
|
||||
}
|
||||
|
||||
if(callback(instance))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Slice Buses implementation with Assert(false), this will exist only during Slice->Prefab
|
||||
// development to pinpoint and replace specific calls to Slice system
|
||||
|
||||
+6
@@ -169,11 +169,17 @@ namespace AzToolsFramework
|
||||
void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) override;
|
||||
bool IsRootPrefabAssigned() const override;
|
||||
|
||||
Prefab::InstanceOptionalReference GetInstanceReferenceFromRootAliasPath(Prefab::RootAliasPath rootAliasPath) const override;
|
||||
bool GetInstancesInRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const override;
|
||||
|
||||
protected:
|
||||
|
||||
AZ::SliceComponent::SliceInstanceAddress GetOwningSlice() override;
|
||||
|
||||
private:
|
||||
bool IsValidRootAliasPath(Prefab::RootAliasPath rootAliasPath) const;
|
||||
|
||||
struct PlayInEditorData
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::InMemorySpawnableAssetContainer m_assetsCache;
|
||||
|
||||
@@ -177,7 +177,6 @@ namespace AzToolsFramework
|
||||
AZStd::pair<Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath);
|
||||
AZStd::pair<const Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) const;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the aliases of all the nested instances, which are sourced by the template with the given id.
|
||||
*
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <AzToolsFramework/Commands/SelectionCommand.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
@@ -97,9 +96,9 @@ namespace AzToolsFramework::Prefab
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, selectedEntities);
|
||||
}
|
||||
|
||||
// Edit Prefab
|
||||
// Add undo element
|
||||
{
|
||||
auto editUndo = aznew PrefabFocusUndo("Edit Prefab");
|
||||
auto editUndo = aznew PrefabFocusUndo("Focus Prefab");
|
||||
editUndo->Capture(entityId);
|
||||
editUndo->SetParent(undoBatch.GetUndoBatch());
|
||||
FocusOnPrefabInstanceOwningEntityId(entityId);
|
||||
@@ -112,15 +111,24 @@ namespace AzToolsFramework::Prefab
|
||||
[[maybe_unused]] AzFramework::EntityContextId entityContextId)
|
||||
{
|
||||
// If only one instance is in the hierarchy, this operation is invalid
|
||||
size_t hierarchySize = m_instanceFocusHierarchy.size();
|
||||
if (hierarchySize <= 1)
|
||||
if (m_rootAliasFocusPathLength <= 1)
|
||||
{
|
||||
return AZ::Failure(
|
||||
AZStd::string("Prefab Focus Handler: Could not complete FocusOnParentOfFocusedPrefab operation while focusing on the root."));
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Prefab Focus Handler: Could not complete FocusOnParentOfFocusedPrefab operation while focusing on the root."));
|
||||
}
|
||||
|
||||
RootAliasPath parentPath = m_rootAliasFocusPath;
|
||||
parentPath.RemoveFilename();
|
||||
|
||||
// Retrieve parent of currently focused prefab.
|
||||
InstanceOptionalReference parentInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[hierarchySize - 2]);
|
||||
InstanceOptionalReference parentInstance = GetInstanceReference(parentPath);
|
||||
|
||||
// If only one instance is in the hierarchy, this operation is invalid
|
||||
if (!parentInstance.has_value())
|
||||
{
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Prefab Focus Handler: Could not retrieve parent of current focus in FocusOnParentOfFocusedPrefab."));
|
||||
}
|
||||
|
||||
// Use container entity of parent Instance for focus operations.
|
||||
AZ::EntityId entityId = parentInstance->get().GetContainerEntityId();
|
||||
@@ -136,9 +144,9 @@ namespace AzToolsFramework::Prefab
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, selectedEntities);
|
||||
}
|
||||
|
||||
// Edit Prefab
|
||||
// Add undo element
|
||||
{
|
||||
auto editUndo = aznew PrefabFocusUndo("Edit Prefab");
|
||||
auto editUndo = aznew PrefabFocusUndo("Focus Prefab");
|
||||
editUndo->Capture(entityId);
|
||||
editUndo->SetParent(undoBatch.GetUndoBatch());
|
||||
FocusOnPrefabInstanceOwningEntityId(entityId);
|
||||
@@ -149,12 +157,31 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
PrefabFocusOperationResult PrefabFocusHandler::FocusOnPathIndex([[maybe_unused]] AzFramework::EntityContextId entityContextId, int index)
|
||||
{
|
||||
if (index < 0 || index >= m_instanceFocusHierarchy.size())
|
||||
if (index < 0 || index >= m_rootAliasFocusPathLength)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Prefab Focus Handler: Invalid index on FocusOnPathIndex."));
|
||||
}
|
||||
|
||||
InstanceOptionalReference focusedInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[index]);
|
||||
int i = 0;
|
||||
RootAliasPath indexedPath;
|
||||
for (const auto& pathElement : m_rootAliasFocusPath)
|
||||
{
|
||||
indexedPath.Append(pathElement);
|
||||
|
||||
if (i == index)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
InstanceOptionalReference focusedInstance = GetInstanceReference(indexedPath);
|
||||
|
||||
if (!focusedInstance.has_value())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Prefab Focus Handler: Could not retrieve instance at index %i.", index));
|
||||
}
|
||||
|
||||
return FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId());
|
||||
}
|
||||
@@ -192,13 +219,14 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
|
||||
// Close all container entities in the old path.
|
||||
CloseInstanceContainers(m_instanceFocusHierarchy);
|
||||
SetInstanceContainersOpenState(m_rootAliasFocusPath, false);
|
||||
|
||||
AZ::EntityId previousContainerEntityId = m_focusedInstanceContainerEntityId;
|
||||
const RootAliasPath previousContainerRootAliasPath = m_rootAliasFocusPath;
|
||||
const InstanceOptionalConstReference previousFocusedInstance = GetInstanceReference(previousContainerRootAliasPath);
|
||||
|
||||
// Do not store the container for the root instance, use an invalid EntityId instead.
|
||||
m_focusedInstanceContainerEntityId = focusedInstance->get().GetParentInstance().has_value() ? focusedInstance->get().GetContainerEntityId() : AZ::EntityId();
|
||||
m_rootAliasFocusPath = focusedInstance->get().GetAbsoluteInstanceAliasPath();
|
||||
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
|
||||
m_rootAliasFocusPathLength = aznumeric_cast<int>(AZStd::distance(m_rootAliasFocusPath.begin(), m_rootAliasFocusPath.end()));
|
||||
|
||||
// Focus on the descendants of the container entity in the Editor, if the interface is initialized.
|
||||
if (m_focusModeInterface)
|
||||
@@ -214,15 +242,22 @@ namespace AzToolsFramework::Prefab
|
||||
// Refresh the read-only cache, if the interface is initialized.
|
||||
if (m_readOnlyEntityQueryInterface)
|
||||
{
|
||||
m_readOnlyEntityQueryInterface->RefreshReadOnlyState({ previousContainerEntityId, m_focusedInstanceContainerEntityId });
|
||||
EntityIdList containerEntities;
|
||||
|
||||
if (previousFocusedInstance.has_value())
|
||||
{
|
||||
containerEntities.push_back(previousFocusedInstance->get().GetContainerEntityId());
|
||||
}
|
||||
containerEntities.push_back(focusedInstance->get().GetContainerEntityId());
|
||||
|
||||
m_readOnlyEntityQueryInterface->RefreshReadOnlyState(containerEntities);
|
||||
}
|
||||
|
||||
// Refresh path variables.
|
||||
RefreshInstanceFocusList();
|
||||
RefreshInstanceFocusPath();
|
||||
|
||||
// Open all container entities in the new path.
|
||||
OpenInstanceContainers(m_instanceFocusHierarchy);
|
||||
SetInstanceContainersOpenState(m_rootAliasFocusPath, true);
|
||||
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
|
||||
@@ -237,17 +272,12 @@ namespace AzToolsFramework::Prefab
|
||||
InstanceOptionalReference PrefabFocusHandler::GetFocusedPrefabInstance(
|
||||
[[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
return GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
|
||||
return GetInstanceReference(m_rootAliasFocusPath);
|
||||
}
|
||||
|
||||
AZ::EntityId PrefabFocusHandler::GetFocusedPrefabContainerEntityId([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
if (m_focusedInstanceContainerEntityId.IsValid())
|
||||
{
|
||||
return m_focusedInstanceContainerEntityId;
|
||||
}
|
||||
|
||||
if (auto instance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId); instance.has_value())
|
||||
if (const InstanceOptionalConstReference instance = GetInstanceReference(m_rootAliasFocusPath); instance.has_value())
|
||||
{
|
||||
return instance->get().GetContainerEntityId();
|
||||
}
|
||||
@@ -262,19 +292,13 @@ namespace AzToolsFramework::Prefab
|
||||
return false;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
const InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
if (!instance.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is owned by the root instance, that corresponds to an invalid m_focusedInstanceContainerEntityId.
|
||||
if (!instance->get().GetParentInstance().has_value())
|
||||
{
|
||||
return !m_focusedInstanceContainerEntityId.IsValid();
|
||||
}
|
||||
|
||||
return (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId);
|
||||
return (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath);
|
||||
}
|
||||
|
||||
bool PrefabFocusHandler::IsOwningPrefabInFocusHierarchy(AZ::EntityId entityId) const
|
||||
@@ -284,18 +308,10 @@ namespace AzToolsFramework::Prefab
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the focus is on the root, m_focusedInstanceContainerEntityId will be the invalid id.
|
||||
// In those case all entities are in the focus hierarchy and should return true.
|
||||
if (!m_focusedInstanceContainerEntityId.IsValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
|
||||
InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
while (instance.has_value())
|
||||
{
|
||||
if (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId)
|
||||
if (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -308,40 +324,47 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
const AZ::IO::Path& PrefabFocusHandler::GetPrefabFocusPath([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
return m_instanceFocusPath;
|
||||
return m_filenameFocusPath;
|
||||
}
|
||||
|
||||
const int PrefabFocusHandler::GetPrefabFocusPathLength([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
return aznumeric_cast<int>(m_instanceFocusHierarchy.size());
|
||||
return m_rootAliasFocusPathLength;
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OnContextReset()
|
||||
{
|
||||
// Clear the old focus vector
|
||||
m_instanceFocusHierarchy.clear();
|
||||
|
||||
// Focus on the root prefab (AZ::EntityId() will default to it)
|
||||
FocusOnPrefabInstanceOwningEntityId(AZ::EntityId());
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OnEntityInfoUpdatedName(AZ::EntityId entityId, [[maybe_unused]]const AZStd::string& name)
|
||||
{
|
||||
// Determine if the entityId is the container for any of the instances in the vector.
|
||||
auto result = AZStd::find_if(
|
||||
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
|
||||
[&, entityId](const AZ::EntityId& containerEntityId)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
return (instance->get().GetContainerEntityId() == entityId);
|
||||
}
|
||||
);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (result != m_instanceFocusHierarchy.end())
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
// Determine if the entityId is the container for any of the instances in the vector.
|
||||
bool match = prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
m_rootAliasFocusPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
if (instance->get().GetContainerEntityId() == entityId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
if (match)
|
||||
{
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,108 +377,81 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
void PrefabFocusHandler::OnPrefabTemplateDirtyFlagUpdated(TemplateId templateId, [[maybe_unused]] bool status)
|
||||
{
|
||||
// Determine if the templateId matches any of the instances in the vector.
|
||||
auto result = AZStd::find_if(
|
||||
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
|
||||
[&, templateId](const AZ::EntityId& containerEntityId)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
return (instance->get().GetTemplateId() == templateId);
|
||||
}
|
||||
);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (result != m_instanceFocusHierarchy.end())
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
}
|
||||
// Determine if the templateId matches any of the instances in the vector.
|
||||
bool match = prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
m_rootAliasFocusPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
if (instance->get().GetTemplateId() == templateId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::RefreshInstanceFocusList()
|
||||
{
|
||||
m_instanceFocusHierarchy.clear();
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
AZStd::list<InstanceOptionalReference> instanceFocusList;
|
||||
|
||||
InstanceOptionalReference currentInstance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
|
||||
while (currentInstance.has_value())
|
||||
{
|
||||
if (currentInstance->get().GetParentInstance().has_value())
|
||||
if (match)
|
||||
{
|
||||
m_instanceFocusHierarchy.emplace_back(currentInstance->get().GetContainerEntityId());
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_instanceFocusHierarchy.emplace_back(AZ::EntityId());
|
||||
}
|
||||
|
||||
currentInstance = currentInstance->get().GetParentInstance();
|
||||
}
|
||||
|
||||
// Invert the vector, since we need the top instance to be at index 0.
|
||||
AZStd::reverse(m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end());
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::RefreshInstanceFocusPath()
|
||||
{
|
||||
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
|
||||
m_instanceFocusPath.clear();
|
||||
|
||||
size_t index = 0;
|
||||
size_t maxIndex = m_instanceFocusHierarchy.size() - 1;
|
||||
|
||||
for (const AZ::EntityId& containerEntityId : m_instanceFocusHierarchy)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
if (instance.has_value())
|
||||
{
|
||||
AZStd::string prefabName;
|
||||
|
||||
if (index < maxIndex)
|
||||
{
|
||||
// Get the filename without the extension (stem).
|
||||
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the full filename.
|
||||
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
|
||||
}
|
||||
|
||||
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
|
||||
{
|
||||
prefabName += "*";
|
||||
}
|
||||
|
||||
m_instanceFocusPath.Append(prefabName);
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
|
||||
{
|
||||
// If this is called outside the Editor, this interface won't be initialized.
|
||||
if (!m_containerEntityInterface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_filenameFocusPath.clear();
|
||||
|
||||
for (const AZ::EntityId& containerEntityId : instances)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
PrefabSystemComponentInterface* prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), true);
|
||||
}
|
||||
if (prefabEditorEntityOwnershipInterface && prefabSystemComponentInterface)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
m_rootAliasFocusPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
if (instance.has_value())
|
||||
{
|
||||
AZStd::string prefabName;
|
||||
|
||||
if (i == m_rootAliasFocusPathLength - 1)
|
||||
{
|
||||
// Get the full filename.
|
||||
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the filename without the extension (stem).
|
||||
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
|
||||
}
|
||||
|
||||
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
|
||||
{
|
||||
prefabName += "*";
|
||||
}
|
||||
|
||||
m_filenameFocusPath.Append(prefabName);
|
||||
}
|
||||
|
||||
++i;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
|
||||
void PrefabFocusHandler::SetInstanceContainersOpenState(const RootAliasPath& rootAliasPath, bool openState) const
|
||||
{
|
||||
// If this is called outside the Editor, this interface won't be initialized.
|
||||
if (!m_containerEntityInterface)
|
||||
@@ -463,33 +459,34 @@ namespace AzToolsFramework::Prefab
|
||||
return;
|
||||
}
|
||||
|
||||
for (const AZ::EntityId& containerEntityId : instances)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), false);
|
||||
}
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
rootAliasPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), openState);
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceOptionalReference PrefabFocusHandler::GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const
|
||||
InstanceOptionalReference PrefabFocusHandler::GetInstanceReference(RootAliasPath rootAliasPath) const
|
||||
{
|
||||
if (!containerEntityId.IsValid())
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
return prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
return prefabEditorEntityOwnershipInterface->GetInstanceReferenceFromRootAliasPath(rootAliasPath);
|
||||
}
|
||||
|
||||
return m_instanceEntityMapperInterface->FindOwningInstance(containerEntityId);
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
|
||||
@@ -28,6 +29,7 @@ namespace AzToolsFramework
|
||||
namespace AzToolsFramework::Prefab
|
||||
{
|
||||
class InstanceEntityMapperInterface;
|
||||
class PrefabSystemComponentInterface;
|
||||
|
||||
//! Handles Prefab Focus mode, determining which prefab file entity changes will target.
|
||||
class PrefabFocusHandler final
|
||||
@@ -73,23 +75,20 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
private:
|
||||
PrefabFocusOperationResult FocusOnPrefabInstance(InstanceOptionalReference focusedInstance);
|
||||
void RefreshInstanceFocusList();
|
||||
void RefreshInstanceFocusPath();
|
||||
|
||||
void OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
|
||||
void CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
|
||||
void SetInstanceContainersOpenState(const RootAliasPath& rootAliasPath, bool openState) const;
|
||||
|
||||
InstanceOptionalReference GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const;
|
||||
InstanceOptionalReference GetInstanceReference(RootAliasPath rootAliasPath) const;
|
||||
|
||||
//! The EntityId of the prefab container entity for the instance the editor is currently focusing on.
|
||||
AZ::EntityId m_focusedInstanceContainerEntityId = AZ::EntityId();
|
||||
//! The alias path for the instance the editor is currently focusing on, starting from the root instance.
|
||||
RootAliasPath m_rootAliasFocusPath = RootAliasPath();
|
||||
//! The templateId of the focused instance.
|
||||
TemplateId m_focusedTemplateId;
|
||||
//! The list of instances going from the root (index 0) to the focused instance,
|
||||
//! referenced by their prefab container's EntityId.
|
||||
AZStd::vector<AZ::EntityId> m_instanceFocusHierarchy;
|
||||
//! A path containing the filenames of the instances in the focus hierarchy, separated with a /.
|
||||
AZ::IO::Path m_instanceFocusPath;
|
||||
AZ::IO::Path m_filenameFocusPath;
|
||||
//! The length of the current focus path. Stored to simplify internal checks.
|
||||
int m_rootAliasFocusPathLength = 0;
|
||||
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
|
||||
@@ -815,7 +815,8 @@ namespace AzToolsFramework
|
||||
|
||||
if (templateRef.has_value())
|
||||
{
|
||||
return templateRef->get().IsDirty();
|
||||
return !templateRef->get().IsProcedural() && // all procedural prefabs are read-only
|
||||
templateRef->get().IsDirty();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
StatementPrototype stmt("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=:1;");
|
||||
StatementPrototype stmt("SELECT COUNT(*) FROM sqlite_schema WHERE type='table' AND name=:1;");
|
||||
Statement* execute = stmt.Prepare(m_db); // execute now belongs to stmt and will die when stmt leaves scope.
|
||||
if (!execute->Prepared())
|
||||
{
|
||||
@@ -501,7 +501,7 @@ namespace AzToolsFramework
|
||||
// https://www.sqlite.org/c3ref/prepare.html ^^^^^^^^^
|
||||
|
||||
int res = sqlite3_prepare_v2(db, m_parentPrototype->GetSqlText().c_str(), (int)m_parentPrototype->GetSqlText().length() + 1, &m_statement, NULL);
|
||||
|
||||
|
||||
AZ_Assert(res == SQLITE_OK, "Statement::PrepareFirstTime: failed! %s ( prototype is '%s'). Error code returned is %d.", sqlite3_errmsg(db), m_parentPrototype->GetSqlText().c_str(), res);
|
||||
return ((res == SQLITE_OK)&&(m_statement));
|
||||
}
|
||||
@@ -703,7 +703,7 @@ namespace AzToolsFramework
|
||||
int res = sqlite3_clear_bindings(m_statement);
|
||||
AZ_Assert(res == SQLITE_OK, "Statement::sqlite3_clear_bindings: failed!");
|
||||
return (res == SQLITE_OK);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int Statement::GetNamedParamIdx(const char* name)
|
||||
|
||||
+1
@@ -783,6 +783,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
EBUS_EVENT(ToolsApplicationEvents::Bus, InvalidatePropertyDisplay, Refresh_EntireTree);
|
||||
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::Bus::Events::AddDirtyEntity, GetEntityId());
|
||||
}
|
||||
|
||||
void ScriptEditorComponent::LoadProperties()
|
||||
|
||||
@@ -306,41 +306,37 @@ namespace AzToolsFramework
|
||||
{
|
||||
// Only show the close icon if the prefab is expanded.
|
||||
// This allows the prefab container to be opened if it was collapsed during propagation.
|
||||
if (!isExpanded)
|
||||
if (isExpanded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Use the same color as the background.
|
||||
QColor backgroundColor = m_backgroundColor;
|
||||
if (isSelected)
|
||||
{
|
||||
backgroundColor = m_backgroundSelectedColor;
|
||||
}
|
||||
else if (isHovered)
|
||||
{
|
||||
backgroundColor = m_backgroundHoverColor;
|
||||
}
|
||||
|
||||
// Use the same color as the background.
|
||||
QColor backgroundColor = m_backgroundColor;
|
||||
if (isSelected)
|
||||
{
|
||||
backgroundColor = m_backgroundSelectedColor;
|
||||
}
|
||||
else if (isHovered)
|
||||
{
|
||||
backgroundColor = m_backgroundHoverColor;
|
||||
}
|
||||
// Paint a rect to cover up the expander.
|
||||
QRect rect = QRect(0, 0, 16, 16);
|
||||
rect.translate(option.rect.topLeft() + offset);
|
||||
painter->fillRect(rect, backgroundColor);
|
||||
|
||||
// Paint a rect to cover up the expander.
|
||||
QRect rect = QRect(0, 0, 16, 16);
|
||||
rect.translate(option.rect.topLeft() + offset);
|
||||
painter->fillRect(rect, backgroundColor);
|
||||
|
||||
// Paint the icon.
|
||||
QIcon closeIcon = QIcon(m_prefabEditCloseIconPath);
|
||||
painter->drawPixmap(option.rect.topLeft() + offset, closeIcon.pixmap(iconSize));
|
||||
// Paint the icon.
|
||||
QIcon closeIcon = QIcon(m_prefabEditCloseIconPath);
|
||||
painter->drawPixmap(option.rect.topLeft() + offset, closeIcon.pixmap(iconSize));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only show the edit icon on hover.
|
||||
if (!isHovered)
|
||||
if (isHovered)
|
||||
{
|
||||
return;
|
||||
QIcon openIcon = QIcon(m_prefabEditOpenIconPath);
|
||||
painter->drawPixmap(option.rect.topLeft() + offset, openIcon.pixmap(iconSize));
|
||||
}
|
||||
|
||||
QIcon openIcon = QIcon(m_prefabEditOpenIconPath);
|
||||
painter->drawPixmap(option.rect.topLeft() + offset, openIcon.pixmap(iconSize));
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ namespace AzToolsFramework
|
||||
|
||||
EditorInteractionSystemViewportSelectionRequestBus::Event(
|
||||
GetEntityContextId(), &EditorInteractionSystemViewportSelection::SetHandler,
|
||||
[](const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
[](const EditorVisibleEntityDataCacheInterface* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
{
|
||||
return AZStd::make_unique<EditorPickEntitySelection>(entityDataCache, viewportEditorModeTracker);
|
||||
});
|
||||
|
||||
+55
@@ -90,6 +90,61 @@ namespace UnitTest
|
||||
return AZStd::string(keyText.toUtf8().data());
|
||||
}
|
||||
|
||||
bool ViewportSettingsTestImpl::GridSnappingEnabled() const
|
||||
{
|
||||
return m_gridSnapping;
|
||||
}
|
||||
|
||||
float ViewportSettingsTestImpl::GridSize() const
|
||||
{
|
||||
return m_gridSize;
|
||||
}
|
||||
|
||||
bool ViewportSettingsTestImpl::ShowGrid() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ViewportSettingsTestImpl::AngleSnappingEnabled() const
|
||||
{
|
||||
return m_angularSnapping;
|
||||
}
|
||||
|
||||
float ViewportSettingsTestImpl::AngleStep() const
|
||||
{
|
||||
return m_angularStep;
|
||||
}
|
||||
|
||||
float ViewportSettingsTestImpl::ManipulatorLineBoundWidth() const
|
||||
{
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
float ViewportSettingsTestImpl::ManipulatorCircleBoundWidth() const
|
||||
{
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
bool ViewportSettingsTestImpl::StickySelectEnabled() const
|
||||
{
|
||||
return m_stickySelect;
|
||||
}
|
||||
|
||||
bool ViewportSettingsTestImpl::IconsVisible() const
|
||||
{
|
||||
return m_iconsVisible;
|
||||
}
|
||||
|
||||
bool ViewportSettingsTestImpl::HelpersVisible() const
|
||||
{
|
||||
return m_helpersVisible;
|
||||
}
|
||||
|
||||
AZ::Vector3 ViewportSettingsTestImpl::DefaultEditorCameraPosition() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool TestWidget::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
AZ_UNUSED(watched);
|
||||
|
||||
+38
-1
@@ -91,6 +91,43 @@ namespace UnitTest
|
||||
/// @param modifiers Optional keyboard modifiers to include during the wheel events, defaults to Qt::NoModifier
|
||||
AZStd::string QtKeyToAzString(Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
|
||||
|
||||
//! Test implementation of the ViewportSettingsRequestBus.
|
||||
//! @note Can be used to customize viewport settings during test execution.
|
||||
class ViewportSettingsTestImpl : public AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
void Connect(const AzFramework::ViewportId viewportId)
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler::BusConnect(viewportId);
|
||||
}
|
||||
|
||||
void Disconnect()
|
||||
{
|
||||
AzToolsFramework::ViewportInteraction::ViewportSettingsRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
// ViewportSettingsRequestBus overrides ...
|
||||
bool GridSnappingEnabled() const override;
|
||||
float GridSize() const override;
|
||||
bool ShowGrid() const override;
|
||||
bool AngleSnappingEnabled() const override;
|
||||
float AngleStep() const override;
|
||||
float ManipulatorLineBoundWidth() const override;
|
||||
float ManipulatorCircleBoundWidth() const override;
|
||||
bool StickySelectEnabled() const override;
|
||||
AZ::Vector3 DefaultEditorCameraPosition() const override;
|
||||
bool IconsVisible() const override;
|
||||
bool HelpersVisible() const override;
|
||||
|
||||
float m_gridSize = 1.0f;
|
||||
float m_angularStep = 0.0f;
|
||||
bool m_gridSnapping = false;
|
||||
bool m_angularSnapping = false;
|
||||
bool m_stickySelect = true;
|
||||
bool m_iconsVisible = true;
|
||||
bool m_helpersVisible = true;
|
||||
};
|
||||
|
||||
/// Test widget to store QActions generated by EditorTransformComponentSelection.
|
||||
class TestWidget : public QWidget
|
||||
{
|
||||
@@ -207,7 +244,7 @@ namespace UnitTest
|
||||
m_editorActions.Connect();
|
||||
|
||||
const auto viewportHandlerBuilder =
|
||||
[this](const AzToolsFramework::EditorVisibleEntityDataCache* entityDataCache,
|
||||
[this](const AzToolsFramework::EditorVisibleEntityDataCacheInterface* entityDataCache,
|
||||
[[maybe_unused]] AzToolsFramework::ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
{
|
||||
// create the default viewport (handles ComponentMode)
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/API/EditorViewportIconDisplayInterface.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class MockEditorViewportIconDisplayInterface : public AZ::Interface<AzToolsFramework::EditorViewportIconDisplayInterface>::Registrar
|
||||
{
|
||||
public:
|
||||
virtual ~MockEditorViewportIconDisplayInterface() = default;
|
||||
|
||||
//! AzToolsFramework::EditorViewportIconDisplayInterface overrides ...
|
||||
MOCK_METHOD1(DrawIcon, void(const DrawParameters&));
|
||||
MOCK_METHOD1(GetOrLoadIconForPath, IconId(AZStd::string_view path));
|
||||
MOCK_METHOD1(GetIconLoadStatus, IconLoadStatus(IconId icon));
|
||||
};
|
||||
} // namespace UnitTest
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/ViewportSelection/EditorVisibleEntityDataCache.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class MockEditorVisibleEntityDataCacheInterface : public AzToolsFramework::EditorVisibleEntityDataCacheInterface
|
||||
{
|
||||
using ComponentEntityAccentType = AzToolsFramework::Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType;
|
||||
|
||||
public:
|
||||
virtual ~MockEditorVisibleEntityDataCacheInterface() = default;
|
||||
|
||||
// AzToolsFramework::EditorVisibleEntityDataCacheInterface overrides ...
|
||||
MOCK_CONST_METHOD0(VisibleEntityDataCount, size_t());
|
||||
MOCK_CONST_METHOD1(GetVisibleEntityPosition, AZ::Vector3(size_t));
|
||||
MOCK_CONST_METHOD1(GetVisibleEntityTransform, const AZ::Transform&(size_t));
|
||||
MOCK_CONST_METHOD1(GetVisibleEntityId, AZ::EntityId(size_t));
|
||||
MOCK_CONST_METHOD1(GetVisibleEntityAccent, ComponentEntityAccentType(size_t));
|
||||
MOCK_CONST_METHOD1(IsVisibleEntityLocked, bool(size_t));
|
||||
MOCK_CONST_METHOD1(IsVisibleEntityVisible, bool(size_t));
|
||||
MOCK_CONST_METHOD1(IsVisibleEntitySelected, bool(size_t));
|
||||
MOCK_CONST_METHOD1(IsVisibleEntityIconHidden, bool(size_t));
|
||||
MOCK_CONST_METHOD1(IsVisibleEntityIndividuallySelectableInViewport, bool(size_t));
|
||||
MOCK_CONST_METHOD1(GetVisibleEntityIndexFromId, AZStd::optional<size_t>(AZ::EntityId entityId));
|
||||
};
|
||||
} // namespace UnitTest
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class MockFocusModeInterface : public AZ::Interface<AzToolsFramework::FocusModeInterface>::Registrar
|
||||
{
|
||||
public:
|
||||
virtual ~MockFocusModeInterface() = default;
|
||||
|
||||
// AzToolsFramework::FocusModeInterface overrides ...
|
||||
MOCK_METHOD1(SetFocusRoot, void(AZ::EntityId entityId));
|
||||
MOCK_METHOD1(ClearFocusRoot, void(AzFramework::EntityContextId entityContextId));
|
||||
MOCK_METHOD1(GetFocusRoot, AZ::EntityId(AzFramework::EntityContextId entityContextId));
|
||||
MOCK_METHOD1(GetFocusedEntities, AzToolsFramework::EntityIdList(AzFramework::EntityContextId entityContextId));
|
||||
MOCK_CONST_METHOD1(IsInFocusSubTree, bool(AZ::EntityId entityId));
|
||||
};
|
||||
} // namespace UnitTest
|
||||
+1
-2
@@ -21,9 +21,8 @@ namespace AzToolsFramework
|
||||
AZ_CLASS_ALLOCATOR_IMPL(EditorDefaultSelection, AZ::SystemAllocator, 0)
|
||||
|
||||
EditorDefaultSelection::EditorDefaultSelection(
|
||||
const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
const EditorVisibleEntityDataCacheInterface* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
: m_phantomWidget(nullptr)
|
||||
, m_entityDataCache(entityDataCache)
|
||||
, m_viewportEditorModeTracker(viewportEditorModeTracker)
|
||||
, m_componentModeCollection(viewportEditorModeTracker)
|
||||
{
|
||||
|
||||
+6
-7
@@ -27,7 +27,8 @@ namespace AzToolsFramework
|
||||
AZ_CLASS_ALLOCATOR_DECL
|
||||
|
||||
//! @cond
|
||||
EditorDefaultSelection(const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker);
|
||||
EditorDefaultSelection(
|
||||
const EditorVisibleEntityDataCacheInterface* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker);
|
||||
EditorDefaultSelection(const EditorDefaultSelection&) = delete;
|
||||
EditorDefaultSelection& operator=(const EditorDefaultSelection&) = delete;
|
||||
virtual ~EditorDefaultSelection();
|
||||
@@ -85,10 +86,8 @@ namespace AzToolsFramework
|
||||
QWidget m_phantomWidget; //!< The phantom widget responsible for holding QActions while in ComponentMode.
|
||||
QWidget* m_phantomOverrideWidget = nullptr; //!< It's possible to override the phantom widget in special circumstances (eg testing).
|
||||
ComponentModeFramework::ComponentModeCollection m_componentModeCollection; //!< Handles all active ComponentMode types.
|
||||
AZStd::unique_ptr<EditorTransformComponentSelection> m_transformComponentSelection =
|
||||
nullptr; //!< Viewport selection (responsible for
|
||||
//!< manipulators and transform modifications).
|
||||
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Reference to cached visible EntityData.
|
||||
//! Viewport selection (responsible for manipulators and transform modifications).
|
||||
AZStd::unique_ptr<EditorTransformComponentSelection> m_transformComponentSelection = nullptr;
|
||||
|
||||
//! Mapping between passed ActionOverride (AddActionOverride) and allocated QAction.
|
||||
struct ActionOverrideMapping
|
||||
@@ -112,7 +111,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::shared_ptr<AzToolsFramework::ManipulatorManager> m_manipulatorManager; //!< The default manipulator manager.
|
||||
ViewportInteraction::MouseInteraction m_currentInteraction; //!< Current mouse interaction to be used for drawing manipulators.
|
||||
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr; //!< Tracker for activating/deactivating viewport editor modes.
|
||||
|
||||
//! Tracker for activating/deactivating viewport editor modes.
|
||||
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+20
-10
@@ -159,7 +159,7 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
EditorHelpers::EditorHelpers(const EditorVisibleEntityDataCache* entityDataCache)
|
||||
EditorHelpers::EditorHelpers(const EditorVisibleEntityDataCacheInterface* entityDataCache)
|
||||
: m_entityDataCache(entityDataCache)
|
||||
{
|
||||
m_focusModeInterface = AZ::Interface<FocusModeInterface>::Get();
|
||||
@@ -344,9 +344,19 @@ namespace AzToolsFramework
|
||||
continue;
|
||||
}
|
||||
|
||||
int iconTextureId = 0;
|
||||
EditorEntityIconComponentRequestBus::EventResult(
|
||||
iconTextureId, entityId, &EditorEntityIconComponentRequests::GetEntityIconTextureId);
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
const AZ::Vector3 entityCameraVector = entityPosition - cameraState.m_position;
|
||||
|
||||
if (const float directionFromCamera = entityCameraVector.Dot(cameraState.m_forward); directionFromCamera < 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const float distanceFromCamera = entityCameraVector.GetLength();
|
||||
if (distanceFromCamera < cameraState.m_nearClip)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
using ComponentEntityAccentType = Components::EditorSelectionAccentSystemComponent::ComponentEntityAccentType;
|
||||
const AZ::Color iconHighlight = [this, entityCacheIndex]()
|
||||
@@ -364,13 +374,13 @@ namespace AzToolsFramework
|
||||
return AZ::Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}();
|
||||
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
const float distanceFromCamera = cameraState.m_position.GetDistance(entityPosition);
|
||||
const float iconSize = GetIconSize(distanceFromCamera);
|
||||
int iconTextureId = 0;
|
||||
EditorEntityIconComponentRequestBus::EventResult(
|
||||
iconTextureId, entityId, &EditorEntityIconComponentRequestBus::Events::GetEntityIconTextureId);
|
||||
|
||||
editorViewportIconDisplay->DrawIcon({ viewportInfo.m_viewportId, iconTextureId, iconHighlight, entityPosition,
|
||||
EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace,
|
||||
AZ::Vector2{ iconSize, iconSize } });
|
||||
editorViewportIconDisplay->DrawIcon(EditorViewportIconDisplayInterface::DrawParameters{
|
||||
viewportInfo.m_viewportId, iconTextureId, iconHighlight, entityPosition,
|
||||
EditorViewportIconDisplayInterface::CoordinateSpace::WorldSpace, AZ::Vector2(GetIconSize(distanceFromCamera)) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace AzFramework
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class EditorVisibleEntityDataCache;
|
||||
class EditorVisibleEntityDataCacheInterface;
|
||||
class FocusModeInterface;
|
||||
|
||||
namespace ViewportInteraction
|
||||
@@ -64,7 +64,7 @@ namespace AzToolsFramework
|
||||
|
||||
//! An EditorVisibleEntityDataCache must be passed to EditorHelpers to allow it to
|
||||
//! efficiently read entity data without resorting to EBus calls.
|
||||
explicit EditorHelpers(const EditorVisibleEntityDataCache* entityDataCache);
|
||||
explicit EditorHelpers(const EditorVisibleEntityDataCacheInterface* entityDataCache);
|
||||
EditorHelpers(const EditorHelpers&) = delete;
|
||||
EditorHelpers& operator=(const EditorHelpers&) = delete;
|
||||
~EditorHelpers() = default;
|
||||
@@ -103,7 +103,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZStd::unique_ptr<InvalidClicks> m_invalidClicks; //!< Display for invalid click behavior.
|
||||
|
||||
const EditorVisibleEntityDataCache* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers.
|
||||
const EditorVisibleEntityDataCacheInterface* m_entityDataCache = nullptr; //!< Entity Data queried by the EditorHelpers.
|
||||
const FocusModeInterface* m_focusModeInterface = nullptr; //!< API to interact with focus mode functionality.
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ namespace AzToolsFramework
|
||||
void EditorInteractionSystemComponent::SetDefaultHandler()
|
||||
{
|
||||
SetHandler(
|
||||
[](const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
[](const EditorVisibleEntityDataCacheInterface* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
{
|
||||
return AZStd::make_unique<EditorDefaultSelection>(entityDataCache, viewportEditorModeTracker);
|
||||
});
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class EditorVisibleEntityDataCache;
|
||||
class EditorVisibleEntityDataCacheInterface;
|
||||
class ViewportEditorModeTrackerInterface;
|
||||
|
||||
//! Bus to handle all mouse events originating from the viewport.
|
||||
@@ -34,7 +34,7 @@ namespace AzToolsFramework
|
||||
|
||||
//! Alias for factory function to create a new type implementing the ViewportSelectionRequests interface.
|
||||
using ViewportSelectionRequestsBuilderFn = AZStd::function<AZStd::unique_ptr<ViewportInteraction::InternalViewportSelectionRequests>(
|
||||
const EditorVisibleEntityDataCache*, ViewportEditorModeTrackerInterface*)>;
|
||||
const EditorVisibleEntityDataCacheInterface*, ViewportEditorModeTrackerInterface*)>;
|
||||
|
||||
//! Interface for system component implementing the ViewportSelectionRequests interface.
|
||||
//! This interface also includes a setter to set a custom handler also implementing
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ namespace AzToolsFramework
|
||||
AZ_CLASS_ALLOCATOR_IMPL(EditorPickEntitySelection, AZ::SystemAllocator, 0)
|
||||
|
||||
EditorPickEntitySelection::EditorPickEntitySelection(
|
||||
const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
const EditorVisibleEntityDataCacheInterface* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker)
|
||||
: m_editorHelpers(AZStd::make_unique<EditorHelpers>(entityDataCache))
|
||||
, m_viewportEditorModeTracker(viewportEditorModeTracker)
|
||||
{
|
||||
|
||||
+4
-2
@@ -13,6 +13,7 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class EditorVisibleEntityDataCacheInterface;
|
||||
class ViewportEditorModeTrackerInterface;
|
||||
|
||||
//! Viewport interaction that will handle assigning an entity in the viewport to
|
||||
@@ -23,7 +24,7 @@ namespace AzToolsFramework
|
||||
AZ_CLASS_ALLOCATOR_DECL
|
||||
|
||||
EditorPickEntitySelection(
|
||||
const EditorVisibleEntityDataCache* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker);
|
||||
const EditorVisibleEntityDataCacheInterface* entityDataCache, ViewportEditorModeTrackerInterface* viewportEditorModeTracker);
|
||||
~EditorPickEntitySelection();
|
||||
|
||||
private:
|
||||
@@ -35,6 +36,7 @@ namespace AzToolsFramework
|
||||
AZStd::unique_ptr<EditorHelpers> m_editorHelpers; //!< Editor visualization of entities (icons, shapes, debug visuals etc).
|
||||
AZ::EntityId m_hoveredEntityId; //!< What EntityId is the mouse currently hovering over (if any).
|
||||
AZ::EntityId m_cachedEntityIdUnderCursor; //!< Store the EntityId on each mouse move for use in Display.
|
||||
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr; //!< Tracker for activating/deactivating viewport editor modes.
|
||||
//! Tracker for activating/deactivating viewport editor modes.
|
||||
ViewportEditorModeTrackerInterface* m_viewportEditorModeTracker = nullptr;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+3
-3
@@ -381,7 +381,7 @@ namespace AzToolsFramework
|
||||
EntityIdContainer& selectedEntityIdsBeforeBoxSelect,
|
||||
EntityIdContainer& potentialSelectedEntityIds,
|
||||
EntityIdContainer& potentialDeselectedEntityIds,
|
||||
const EditorVisibleEntityDataCache& entityDataCache,
|
||||
const EditorVisibleEntityDataCacheInterface& entityDataCache,
|
||||
const int viewportId,
|
||||
const ViewportInteraction::KeyboardModifiers currentKeyboardModifiers,
|
||||
const ViewportInteraction::KeyboardModifiers& previousKeyboardModifiers)
|
||||
@@ -958,7 +958,7 @@ namespace AzToolsFramework
|
||||
// (useful in the context of drawing when we only care about entities we can see)
|
||||
// note: return the index if it is selectable, nullopt otherwise
|
||||
static AZStd::optional<size_t> SelectableInVisibleViewportCache(
|
||||
const EditorVisibleEntityDataCache& entityDataCache, const AZ::EntityId entityId)
|
||||
const EditorVisibleEntityDataCacheInterface& entityDataCache, const AZ::EntityId entityId)
|
||||
{
|
||||
if (auto entityIndex = entityDataCache.GetVisibleEntityIndexFromId(entityId))
|
||||
{
|
||||
@@ -1002,7 +1002,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
EditorTransformComponentSelection::EditorTransformComponentSelection(const EditorVisibleEntityDataCache* entityDataCache)
|
||||
EditorTransformComponentSelection::EditorTransformComponentSelection(const EditorVisibleEntityDataCacheInterface* entityDataCache)
|
||||
: m_entityDataCache(entityDataCache)
|
||||
{
|
||||
const AzFramework::EntityContextId entityContextId = GetEntityContextId();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user