using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEngine; using UnityEngine.Playables; using UnityEngine.UIElements; namespace Streamingle.Editor { public sealed partial class AICameraGeneratorWindow { private static readonly string[] GeneratorUxmlPaths = { "Packages/com.mingle.cw-ai/Editor/UI/AICameraGeneratorWindow.uxml", "Assets/Scripts/Editor/TimelineTools/UI/AICameraGeneratorWindow.uxml" }; private static readonly string[] GeneratorUssPaths = { "Packages/com.mingle.cw-ai/Editor/UI/AICameraGeneratorWindow.uss", "Assets/Scripts/Editor/TimelineTools/UI/AICameraGeneratorWindow.uss" }; private VisualElement _generatorUiRoot; private ScrollView _mainScroll; private VisualElement _readinessCard; private Label _readinessTitle; private Label _readinessDetail; private DropdownField _sourceDirectorDropdown; private HelpBox _sourceSummaryBox; private DropdownField _cutRhythmDropdown; private Toggle _freshCandidateToggle; private HelpBox _freshCandidateWarning; private Button _generateFullButton; private VisualElement _refinementCard; private VisualElement _selectedShotPickerRow; private HelpBox _selectedShotInfo; private DropdownField _selectedShotDropdown; private Foldout _shotOptionsFoldout; private DropdownField _shotSizeDropdown; private DropdownField _motionDropdown; private DropdownField _compositionDropdown; private Slider _motionIntensitySlider; private FloatField _distanceField; private Slider _bodyFollowSlider; private Button _resetShotOptionsButton; private Button _regenerateShotButton; private Button _removeResultButton; private VisualElement _finalCard; private Foldout _feedbackFoldout; private TextField _editorStyleIdField; private Button _recordCorrectionButton; private Button _saveFinalSceneButton; private Foldout _advancedFoldout; private VisualElement _advancedConfigurationHost; private IMGUIContainer _advancedConfigurationGui; private Button _extractDatasetButton; private Button _reapplyFullButton; private Button _reapplyShotButton; private Button _buildCacheButton; private Button _refreshDiagnosticsButton; private Button _clearLogButton; private TextField _logField; private VisualElement _statusFooter; private Label _statusMessage; private Label _generationStageLabel; private ProgressBar _generationProgress; private Label _generationTimingLabel; private HelpBox _appliedSeedBox; private Button _statusLogButton; private Button _cancelGenerationButton; private IVisualElementScheduledItem _generatorUiRefreshItem; private PlayableDirector[] _uiSourceDirectors = Array.Empty(); private PlayableDirector _uiRenderedSourceDirector; private string _uiShotSignature = string.Empty; private string _uiRenderedLog = string.Empty; private bool _uiSourceReady; private bool _uiLibraryReady; private string _uiLibraryIssue = string.Empty; private double _nextSourceValidationTime; private double _nextLibraryValidationTime; public void CreateGUI() { _generatorUiRefreshItem?.Pause(); var root = rootVisualElement; root.Clear(); try { var uxmlPath = ResolveUiAssetPathForTests(false); var visualTree = string.IsNullOrWhiteSpace(uxmlPath) ? null : AssetDatabase.LoadAssetAtPath(uxmlPath); if (visualTree == null) { throw new FileNotFoundException( "AI 카메라 생성 UXML을 찾을 수 없습니다.", uxmlPath); } visualTree.CloneTree(root); var ussPath = ResolveUiAssetPathForTests(true); var styleSheet = string.IsNullOrWhiteSpace(ussPath) ? null : AssetDatabase.LoadAssetAtPath(ussPath); if (styleSheet != null && !root.styleSheets.Contains(styleSheet)) { root.styleSheets.Add(styleSheet); } CacheGeneratorUiElements(); BuildAdvancedConfigurationUi(); RegisterGeneratorUiCallbacks(); RefreshGeneratorUi(true); if (styleSheet == null) { _generatorUiRoot.Insert( 0, new HelpBox( "스타일 파일을 찾지 못해 기본 Unity 스타일로 표시합니다.", HelpBoxMessageType.Warning)); } _generatorUiRefreshItem = root.schedule .Execute(() => RefreshGeneratorUi(false)) .Every(200); } catch (Exception exception) { BuildGeneratorUiFallback(exception); } } internal static string ResolveUiAssetPathForTests(bool styleSheet) { var candidates = styleSheet ? GeneratorUssPaths : GeneratorUxmlPaths; foreach (var candidate in candidates) { var asset = styleSheet ? (UnityEngine.Object)AssetDatabase.LoadAssetAtPath( candidate) : AssetDatabase.LoadAssetAtPath(candidate); if (asset != null) { return candidate; } } return string.Empty; } private void CacheGeneratorUiElements() { _generatorUiRoot = RequireUi("camera-generator-root"); _mainScroll = RequireUi("main-scroll"); _readinessCard = RequireUi("readiness-card"); _readinessTitle = RequireUi