using System.Collections.Generic; using System.Linq; using AssetBank.DockableWindow.UIHelper; using AssetBank.Editor.DockableWindow; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; namespace AssetBank.DockableWindow { public class ProjectExporterWindow : EditorWindow { private ProjectExporterController _controller; private VisualElement _rootElement; private VisualElement _contentContainer; private Dictionary _assetTrees; private string _currentTab = "General"; // Default to General tab // Checkbox states for the General tab, now a dictionary private Dictionary _exportStates = new Dictionary(); [MenuItem("Tools/GUI/Project Exporter")] public static void ShowWindow() { var wnd = GetWindow(); wnd.titleContent = new GUIContent("Project Exporter", EditorGUIUtility.IconContent("d_Profiler.GlobalIllumination").image); wnd.minSize = new Vector2(400, 300); } private void OnEnable() { _controller = new ProjectExporterController(); _assetTrees = new Dictionary(); _rootElement = rootVisualElement; // Initialize export states for all categories foreach (var category in ProjectExporterCategories.All) { _exportStates[category] = true; } BuildUI(); RefreshContent(_currentTab); } private void BuildUI() { _rootElement.Clear(); var tabContainer = new VisualElement { style = { flexDirection = FlexDirection.Row } }; // General Tab var generalTabButton = ProjectExporterUI.CreateTab("General"); generalTabButton.clicked += () => RefreshContent("General"); tabContainer.Add(generalTabButton); // Dynamic Tabs foreach (var category in ProjectExporterCategories.All) { var tabButton = ProjectExporterUI.CreateTab(category); tabButton.clicked += () => RefreshContent(category); tabContainer.Add(tabButton); } _rootElement.Add(tabContainer); var scrollView = new ScrollView(ScrollViewMode.Vertical); _rootElement.Add(scrollView); _contentContainer = ProjectExporterUI.CreateMainContainer(); scrollView.Add(_contentContainer); var generateButton = ProjectExporterUI.CreateGenerateButton(_currentTab == "General"); _rootElement.Add(generateButton); generateButton.clicked += () => { if (_currentTab == "General") { PerformBulkExport(); } else if (_assetTrees.ContainsKey(_currentTab)) { _controller.ExportAssets(_assetTrees[_currentTab]); } }; } private void RefreshContent(string tabName) { _currentTab = tabName; _contentContainer.Clear(); if (tabName == "General") { DrawGeneralTab(); return; } if (!_assetTrees.ContainsKey(tabName)) { ProjectExporterDataHelper.LoadAssetTree(_assetTrees, _controller, tabName); } var rootModel = _assetTrees[tabName]; if (rootModel != null) { foreach (var child in rootModel.Children) { _contentContainer.Add(CreateAssetView(child, 0)); } } } private void DrawGeneralTab() { var title = new Label("Select Export Types") { style = { unityFontStyleAndWeight = FontStyle.Bold } }; _contentContainer.Add(title); foreach (var category in ProjectExporterCategories.All) { var toggle = ProjectExporterUI.CreateToggle($"Export {category}", _exportStates[category], evt => _exportStates[category] = evt.newValue); _contentContainer.Add(toggle); } } private void PerformBulkExport() { foreach (var category in ProjectExporterCategories.All) { if (_exportStates[category]) { ExportAllOfType(category); } } EditorUtility.DisplayDialog("Bulk Export", "Bulk export process finished.", "OK"); } private void ExportAllOfType(string type) { if (!_assetTrees.ContainsKey(type)) { ProjectExporterDataHelper.LoadAssetTree(_assetTrees, _controller, type); } var rootModel = _assetTrees[type]; if (rootModel != null) { ProjectExporterDataHelper.SetChildrenSelection(rootModel, true); // Select all assets _controller.ExportAssets(rootModel); } } private VisualElement CreateAssetView(AssetModel model, int indentLevel) { const int indentWidth = 20; if (model.Children.Count > 0) { var row = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center, marginLeft = indentLevel * indentWidth } }; var foldout = ProjectExporterUI.CreateFoldout(model.Name); foldout.style.flexGrow = 1; var toggle = new Toggle { value = model.IsSelected, text = "" }; toggle.RegisterValueChangedCallback(evt => { model.IsSelected = evt.newValue; ProjectExporterDataHelper.SetChildrenSelection(model, evt.newValue); UpdateChildTogglesUI(foldout, evt.newValue); }); row.Add(toggle); row.Add(foldout); foreach (var child in model.Children) { foldout.Add(CreateAssetView(child, indentLevel + 1)); } return row; } else { var toggle = ProjectExporterUI.CreateToggle(model.Name); toggle.style.marginLeft = (indentLevel + 1) * indentWidth; toggle.value = model.IsSelected; toggle.RegisterValueChangedCallback(evt => model.IsSelected = evt.newValue); return toggle; } } private void UpdateChildTogglesUI(VisualElement container, bool isSelected) { container.Query().ForEach(childToggle => { childToggle.SetValueWithoutNotify(isSelected); }); } } }