2024-03-07 03:18:00 +08:00
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal ;
2024-03-03 03:51:49 +08:00
using System ;
using System.Reflection ;
2024-03-07 03:18:00 +08:00
using UnityEditor ;
using UnityEngine ;
2024-03-03 03:51:49 +08:00
namespace DCFApixels.DragonECS.Unity.Editors
{
public abstract class EntityTemplateEditorBase : Editor
{
2024-03-05 00:46:47 +08:00
private static readonly Rect RemoveButtonRect = new Rect ( 0f , 0f , 17f , 19f ) ;
private static readonly Rect TooltipIconRect = new Rect ( 0f , 0f , 21f , 15f ) ;
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
private GUIStyle _removeButtonStyle ;
private GenericMenu _genericMenu ;
2024-03-03 03:51:49 +08:00
private bool _isInit = false ;
#region Init
private void Init ( )
{
2024-03-07 21:22:48 +08:00
if ( _genericMenu = = null ) { _isInit = false ; }
2024-03-07 03:18:00 +08:00
if ( _isInit ) { return ; }
2024-03-03 03:51:49 +08:00
2024-03-07 03:18:00 +08:00
var tmpstylebase = UnityEditorUtility . GetStyle ( new Color ( 0.9f , 0f , 0.22f ) , 0.5f ) ;
var tmpStyle = UnityEditorUtility . GetStyle ( new Color ( 1f , 0.5f , 0.7f ) , 0.5f ) ;
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_removeButtonStyle = new GUIStyle ( EditorStyles . linkLabel ) ;
_removeButtonStyle . alignment = TextAnchor . MiddleCenter ;
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_removeButtonStyle . normal = tmpstylebase . normal ;
_removeButtonStyle . hover = tmpStyle . normal ;
_removeButtonStyle . active = tmpStyle . normal ;
_removeButtonStyle . focused = tmpStyle . normal ;
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_removeButtonStyle . padding = new RectOffset ( 0 , 0 , 0 , 0 ) ;
_removeButtonStyle . margin = new RectOffset ( 0 , 0 , 0 , 0 ) ;
_removeButtonStyle . border = new RectOffset ( 0 , 0 , 0 , 0 ) ;
2024-03-03 03:51:49 +08:00
2024-03-07 21:22:48 +08:00
_genericMenu = new GenericMenu ( ) ;
2024-03-03 03:51:49 +08:00
2024-03-06 23:29:54 +08:00
var componentTemplateDummies = ComponentTemplateTypeCache . Dummies ;
foreach ( var dummy in componentTemplateDummies )
2024-03-03 03:51:49 +08:00
{
2024-03-06 23:29:54 +08:00
ITypeMeta meta = dummy is ITypeMeta metaOverride ? metaOverride : dummy . Type . ToMeta ( ) ;
string name = meta . Name ;
string description = meta . Description ;
MetaGroup group = meta . Group ;
2024-03-07 03:18:00 +08:00
if ( group . Name . Length > 0 )
2024-03-06 23:29:54 +08:00
{
name = group . Name + name ;
}
2024-03-03 03:51:49 +08:00
if ( string . IsNullOrEmpty ( description ) = = false )
{
name = $"{name} {EcsUnityConsts.INFO_MARK}" ;
}
2024-03-07 21:22:48 +08:00
_genericMenu . AddItem ( new GUIContent ( name , description ) , false , OnAddComponent , dummy ) ;
2024-03-03 03:51:49 +08:00
}
_isInit = true ;
}
#endregion
#region Add / Remove
private void OnAddComponent ( object obj )
{
Type componentType = obj . GetType ( ) ;
if ( this . target is ITemplateInternal target )
{
SerializedProperty componentsProp = serializedObject . FindProperty ( target . ComponentsPropertyName ) ;
for ( int i = 0 ; i < componentsProp . arraySize ; i + + )
{
if ( componentsProp . GetArrayElementAtIndex ( i ) . managedReferenceValue . GetType ( ) = = componentType )
2024-03-06 21:37:21 +08:00
{
2024-03-03 03:51:49 +08:00
return ;
2024-03-06 21:37:21 +08:00
}
2024-03-03 03:51:49 +08:00
}
componentsProp . InsertArrayElementAtIndex ( 0 ) ;
componentsProp . GetArrayElementAtIndex ( 0 ) . managedReferenceValue = ( ( IComponentTemplate ) obj ) . Clone ( ) ;
serializedObject . ApplyModifiedProperties ( ) ;
EditorUtility . SetDirty ( this . target ) ;
}
}
private void OnRemoveComponentAt ( int index )
{
if ( this . target is ITemplateInternal target )
{
SerializedProperty componentsProp = serializedObject . FindProperty ( target . ComponentsPropertyName ) ;
componentsProp . DeleteArrayElementAtIndex ( index ) ;
serializedObject . ApplyModifiedProperties ( ) ;
EditorUtility . SetDirty ( this . target ) ;
}
}
#endregion
protected void Draw ( ITemplateInternal target )
{
Init ( ) ;
SerializedProperty componentsProp = serializedObject . FindProperty ( target . ComponentsPropertyName ) ;
if ( componentsProp = = null )
2024-03-05 00:46:47 +08:00
{
2024-03-03 03:51:49 +08:00
return ;
2024-03-05 00:46:47 +08:00
}
2024-03-03 03:51:49 +08:00
2024-03-07 03:18:00 +08:00
GUILayout . BeginVertical ( UnityEditorUtility . GetStyle ( Color . black , 0.2f ) ) ;
2024-03-09 03:35:01 +08:00
DrawTop ( target ) ;
2024-03-06 21:37:21 +08:00
GUILayout . Label ( "" , GUILayout . Height ( 0 ) , GUILayout . ExpandWidth ( true ) ) ;
2024-03-03 03:51:49 +08:00
for ( int i = 0 ; i < componentsProp . arraySize ; i + + )
{
DrawComponentData ( componentsProp . GetArrayElementAtIndex ( i ) , i ) ;
}
2024-03-04 07:38:38 +08:00
GUILayout . EndVertical ( ) ;
2024-03-03 03:51:49 +08:00
}
private void DrawTop ( ITemplateInternal target )
{
2024-03-09 03:35:01 +08:00
switch ( EcsGUI . Layout . AddClearComponentButtons ( ) )
2024-03-03 03:51:49 +08:00
{
2024-03-09 03:35:01 +08:00
case EcsGUI . AddClearComponentButton . AddComponent :
Init ( ) ;
_genericMenu . ShowAsContext ( ) ;
break ;
case EcsGUI . AddClearComponentButton . Clear :
Init ( ) ;
serializedObject . FindProperty ( target . ComponentsPropertyName ) . ClearArray ( ) ;
serializedObject . ApplyModifiedProperties ( ) ;
break ;
2024-03-03 03:51:49 +08:00
}
}
2024-03-09 03:35:01 +08:00
2024-03-03 03:51:49 +08:00
private void DrawComponentData ( SerializedProperty componentRefProp , int index )
{
IComponentTemplate template = componentRefProp . managedReferenceValue as IComponentTemplate ;
2024-03-09 03:35:01 +08:00
if ( template = = null | | componentRefProp . managedReferenceValue = = null )
2024-03-03 03:51:49 +08:00
{
DrawDamagedComponent ( componentRefProp , index ) ;
return ;
}
Type componentType ;
SerializedProperty componentProperty = componentRefProp ;
ComponentTemplateBase customInitializer = componentProperty . managedReferenceValue as ComponentTemplateBase ;
if ( customInitializer ! = null )
{
componentProperty = componentRefProp . FindPropertyRelative ( "component" ) ;
componentType = customInitializer . GetType ( ) . GetField ( "component" , BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ) . FieldType ;
}
else
{
2024-03-05 00:46:47 +08:00
componentType = componentProperty . managedReferenceValue . GetType ( ) ; ;
2024-03-03 03:51:49 +08:00
}
2024-03-07 03:18:00 +08:00
2024-03-06 23:29:54 +08:00
ITypeMeta meta = template is ITypeMeta metaOverride ? metaOverride : template . Type . ToMeta ( ) ;
string name = meta . Name ;
string description = meta . Description ;
Color panelColor = meta . Color . ToUnityColor ( ) . Desaturate ( EscEditorConsts . COMPONENT_DRAWER_DESATURATE ) ;
2024-03-03 03:51:49 +08:00
2024-03-07 03:18:00 +08:00
//GUIContent label = new GUIContent(name);
GUIContent label = UnityEditorUtility . GetLabel ( name ) ;
2024-03-05 00:46:47 +08:00
bool isEmpty = componentType . GetFields ( BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ) . Length < = 0 ;
float padding = EditorGUIUtility . standardVerticalSpacing ;
Color alphaPanelColor = panelColor ;
alphaPanelColor . a = EscEditorConsts . COMPONENT_DRAWER_ALPHA ;
2024-03-07 21:22:48 +08:00
Rect removeButtonRect = GUILayoutUtility . GetLastRect ( ) ;
2024-03-06 21:37:21 +08:00
EditorGUI . BeginChangeCheck ( ) ;
2024-03-07 03:18:00 +08:00
GUILayout . BeginVertical ( UnityEditorUtility . GetStyle ( alphaPanelColor ) ) ;
2024-03-05 00:46:47 +08:00
#region Draw Component Block
2024-03-05 03:35:38 +08:00
bool isRemoveComponent = false ;
2024-03-06 21:37:21 +08:00
removeButtonRect . yMin = removeButtonRect . yMax ;
removeButtonRect . yMax + = RemoveButtonRect . height ;
removeButtonRect . xMin = removeButtonRect . xMax - RemoveButtonRect . width ;
removeButtonRect . center + = Vector2 . up * padding * 2f ;
2024-03-05 03:35:38 +08:00
if ( GUI . Button ( removeButtonRect , "x" ) )
{
isRemoveComponent = true ;
}
2024-03-05 00:46:47 +08:00
if ( isEmpty )
2024-03-03 03:51:49 +08:00
{
2024-03-06 21:37:21 +08:00
GUILayout . Label ( label ) ;
2024-03-03 03:51:49 +08:00
}
else
{
2024-03-06 21:37:21 +08:00
EditorGUILayout . PropertyField ( componentProperty , label , true ) ;
2024-03-03 03:51:49 +08:00
}
2024-03-05 03:35:38 +08:00
if ( isRemoveComponent )
2024-03-03 19:59:39 +08:00
{
2024-03-03 03:51:49 +08:00
OnRemoveComponentAt ( index ) ;
2024-03-03 19:59:39 +08:00
}
2024-03-07 03:18:00 +08:00
if ( string . IsNullOrEmpty ( description ) = = false )
2024-03-03 03:51:49 +08:00
{
Rect tooltipIconRect = TooltipIconRect ;
2024-03-06 21:37:21 +08:00
tooltipIconRect . center = removeButtonRect . center ;
tooltipIconRect . center - = Vector2 . right * tooltipIconRect . width ;
2024-03-07 03:18:00 +08:00
GUIContent descriptionLabel = UnityEditorUtility . GetLabel ( EcsUnityConsts . INFO_MARK , description ) ;
2024-03-03 03:51:49 +08:00
GUI . Label ( tooltipIconRect , descriptionLabel , EditorStyles . boldLabel ) ;
}
2024-03-06 21:37:21 +08:00
#endregion
2024-03-05 00:46:47 +08:00
2024-03-06 21:37:21 +08:00
GUILayout . EndVertical ( ) ;
2024-03-05 00:46:47 +08:00
if ( EditorGUI . EndChangeCheck ( ) )
{
componentProperty . serializedObject . ApplyModifiedProperties ( ) ;
2024-03-06 21:37:21 +08:00
EditorUtility . SetDirty ( componentProperty . serializedObject . targetObject ) ;
2024-03-05 00:46:47 +08:00
}
2024-03-03 03:51:49 +08:00
}
private void DrawDamagedComponent ( SerializedProperty componentRefProp , int index )
{
GUILayout . BeginHorizontal ( ) ;
EditorGUILayout . HelpBox ( $"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute" , MessageType . Warning ) ;
Rect lastrect = GUILayoutUtility . GetLastRect ( ) ;
Rect removeButtonRect = RemoveButtonRect ;
removeButtonRect . center = new Vector2 ( lastrect . xMax + removeButtonRect . width , lastrect . yMin + removeButtonRect . height / 2f ) ;
GUILayout . Label ( "" , GUILayout . Width ( removeButtonRect . width ) ) ;
2024-03-07 21:22:48 +08:00
if ( GUI . Button ( removeButtonRect , "x" , _removeButtonStyle ) )
2024-03-06 21:37:21 +08:00
{
2024-03-03 03:51:49 +08:00
OnRemoveComponentAt ( index ) ;
2024-03-06 21:37:21 +08:00
}
2024-03-03 03:51:49 +08:00
GUILayout . EndHorizontal ( ) ;
}
}
[CustomEditor(typeof(ScriptableEntityTemplate), true)]
public class EntityTemplatePresetEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI ( )
{
Draw ( ( ITemplateInternal ) target ) ;
}
}
[CustomEditor(typeof(MonoEntityTemplate), true)]
public class EntityTemplateEditor : EntityTemplateEditorBase
{
public override void OnInspectorGUI ( )
{
Draw ( ( ITemplateInternal ) target ) ;
}
}
}
#endif