using System; using System.Collections.Generic; using System.Reflection; using ShiroginSDK.Runtime.Core.Editor.Models; using ShiroginSDK.Runtime.Core.SDK; using ShiroginSDK.Runtime.Shared.Constants; using UnityEditor; using UnityEngine; // TestDevice struct burada namespace ShiroginSDK.Editor.Windows { /// /// Custom editor window to manage ShiroginConfig settings from a single place. /// public class SDKSettingsWindow : EditorWindow { private ShiroginConfig _config; private bool _hasUnsavedChanges; private ShiroginConfig _originalConfig; private Vector2 _scrollPosition; private void OnEnable() { if (_config == null) { _config = Resources.Load(SDKConstants.ConfigResourcePath); if (_config != null) _originalConfig = Instantiate(_config); } _hasUnsavedChanges = false; } private void OnDestroy() { if (_hasUnsavedChanges && _config != null) { var option = EditorUtility.DisplayDialogComplex("Unsaved Changes", "You have unsaved changes. What would you like to do?", "Save", "Don't Save", "Cancel"); switch (option) { case 0: SaveConfig(); break; case 1: if (_originalConfig != null) EditorUtility.CopySerializedIfDifferent(_originalConfig, _config); break; case 2: break; } } } private void OnGUI() { if (_config == null) { EditorGUILayout.HelpBox("ShiroginConfig.asset not found in Resources folder.", MessageType.Warning); if (GUILayout.Button("Create New Config")) CreateConfigAsset(); return; } _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition); EditorGUI.BeginChangeCheck(); EditorGUILayout.LabelField("ShiroginSDK Settings", EditorStyles.boldLabel); EditorGUILayout.Space(); DrawConfigFields(); EditorGUILayout.EndScrollView(); if (EditorGUI.EndChangeCheck()) _hasUnsavedChanges = HasConfigChanged(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); GUI.enabled = _hasUnsavedChanges; if (GUILayout.Button("Save Changes", GUILayout.Height(30))) SaveConfig(); GUI.enabled = true; if (_hasUnsavedChanges) EditorGUILayout.LabelField("*Unsaved changes", EditorStyles.miniLabel); EditorGUILayout.EndHorizontal(); } [MenuItem("ShiroginSDK/Settings", false, 1)] public static void ShowWindow() { GetWindow("ShiroginSDK Settings"); } private void DrawConfigFields() { var fields = typeof(ShiroginConfig).GetFields(BindingFlags.Public | BindingFlags.Instance); var categories = new Dictionary>(); foreach (var field in fields) { var category = GetFieldCategory(field.Name); if (!categories.ContainsKey(category)) categories[category] = new List(); categories[category].Add(field); } // Can Change field type here to support other field types var orderedCategories = new List { "General Settings", "AppLovin Settings", "Firebase Settings", "AppsFlyer Settings", "Unity Services", "Test Devices" // En sonda }; foreach (var categoryName in orderedCategories) if (categories.ContainsKey(categoryName)) { EditorGUILayout.LabelField(categoryName, EditorStyles.boldLabel); foreach (var field in categories[categoryName]) DrawField(field); EditorGUILayout.Space(); } } private string GetFieldCategory(string fieldName) { if (fieldName.ToLower().Contains("testdevice")) return "Test Devices"; if (fieldName.ToLower().Contains("applovin")) return "AppLovin Settings"; if (fieldName.ToLower().Contains("firebase")) return "Firebase Settings"; if (fieldName.ToLower().Contains("appsflyer")) return "AppsFlyer Settings"; if (fieldName.ToLower().Contains("unity")) return "Unity Services"; return "General Settings"; } private void DrawField(FieldInfo field) { var fieldType = field.FieldType; var fieldName = ObjectNames.NicifyVariableName(field.Name); var currentValue = field.GetValue(_config); if (fieldType == typeof(string)) { var newValue = EditorGUILayout.TextField(fieldName, (string)currentValue ?? ""); field.SetValue(_config, newValue); } else if (fieldType == typeof(bool)) { var newValue = EditorGUILayout.Toggle(fieldName, (bool)currentValue); field.SetValue(_config, newValue); } else if (fieldType == typeof(int)) { var newValue = EditorGUILayout.IntField(fieldName, (int)currentValue); field.SetValue(_config, newValue); } else if (fieldType == typeof(float)) { var newValue = EditorGUILayout.FloatField(fieldName, (float)currentValue); field.SetValue(_config, newValue); } else if (fieldType.IsEnum) { var newValue = EditorGUILayout.EnumPopup(fieldName, (Enum)currentValue); field.SetValue(_config, newValue); } else if (fieldType == typeof(Vector2)) { var newValue = EditorGUILayout.Vector2Field(fieldName, (Vector2)currentValue); field.SetValue(_config, newValue); } else if (fieldType == typeof(Vector3)) { var newValue = EditorGUILayout.Vector3Field(fieldName, (Vector3)currentValue); field.SetValue(_config, newValue); } else if (fieldType == typeof(Color)) { var newValue = EditorGUILayout.ColorField(fieldName, (Color)currentValue); field.SetValue(_config, newValue); } else if (fieldType == typeof(TestDevice[])) // Custom struct array { var list = currentValue as TestDevice[]; if (list == null) list = new TestDevice[0]; EditorGUILayout.LabelField(fieldName, EditorStyles.boldLabel); var newSize = EditorGUILayout.IntField("Size", list.Length); if (newSize != list.Length) Array.Resize(ref list, newSize); for (var i = 0; i < list.Length; i++) { EditorGUILayout.BeginVertical("box"); list[i].deviceName = EditorGUILayout.TextField("Device Name", list[i].deviceName); list[i].deviceId = EditorGUILayout.TextField("Device ID", list[i].deviceId); EditorGUILayout.EndVertical(); } field.SetValue(_config, list); } else { EditorGUILayout.LabelField(fieldName, currentValue?.ToString() ?? "null"); } } private bool HasConfigChanged() { if (_originalConfig == null) return false; var fields = typeof(ShiroginConfig).GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (var field in fields) { var currentValue = field.GetValue(_config); var originalValue = field.GetValue(_originalConfig); if (!Equals(currentValue, originalValue)) return true; } return false; } private void SaveConfig() { if (_config != null) { EditorUtility.SetDirty(_config); AssetDatabase.SaveAssetIfDirty(_config); _originalConfig = Instantiate(_config); _hasUnsavedChanges = false; Debug.Log("[ShiroginSDK] Settings saved successfully."); } } private void CreateConfigAsset() { _config = CreateInstance(); var folderPath = "Assets/Resources"; if (!AssetDatabase.IsValidFolder(folderPath)) AssetDatabase.CreateFolder("Assets", "Resources"); var assetPath = $"{folderPath}/ShiroginConfig.asset"; AssetDatabase.CreateAsset(_config, assetPath); AssetDatabase.SaveAssets(); Debug.Log("[ShiroginSDK] Created new ShiroginConfig.asset at " + assetPath); Selection.activeObject = _config; _originalConfig = Instantiate(_config); _hasUnsavedChanges = false; } } }