using System; using System.Collections.Generic; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.U2D.Animation; using UnityEngine.UIElements; namespace UnityEditor.U2D.Animation.SpriteLibraryEditor { #if ENABLE_UXML_SERIALIZED_DATA [UxmlElement] #endif internal partial class EditorMainWindow : VisualElement { #if ENABLE_UXML_TRAITS public class CustomUxmlFactory : UxmlFactory<EditorMainWindow, UxmlTraits> { } #endif ViewEvents m_ViewEvents; CategoriesTab m_CategoriesTab; LabelsTab m_LabelsTab; TwoPaneSplitView m_SplitView; const float k_MinPaneWidth = 150f; internal void BindElements(ControllerEvents controllerEvents, ViewEvents viewEvents) { m_ViewEvents = viewEvents; m_CategoriesTab = this.Q<CategoriesTab>(); m_CategoriesTab.BindElements(controllerEvents, viewEvents); m_LabelsTab = this.Q<LabelsTab>(); m_LabelsTab.BindElements(controllerEvents, viewEvents); RegisterCallback<GeometryChangedEvent>(GeometryInitialized); } void GeometryInitialized(GeometryChangedEvent evt) { m_SplitView = this.Q<TwoPaneSplitView>(); m_SplitView.fixedPaneInitialDimension = m_SplitView.resolvedStyle.width * SpriteLibraryEditorWindow.Settings.splitPaneSize; m_SplitView.fixedPane.style.minWidth = m_SplitView.flexedPane.style.minWidth = k_MinPaneWidth; m_SplitView.flexedPane.RegisterCallback<GeometryChangedEvent>(OnSplitViewResize); UnregisterCallback<GeometryChangedEvent>(GeometryInitialized); } void OnSplitViewResize(GeometryChangedEvent evt) { m_ViewEvents.onMainUISplitPaneSizeChanged?.Invoke(1f - evt.newRect.width / m_SplitView.resolvedStyle.width); } } #if ENABLE_UXML_SERIALIZED_DATA [UxmlElement] #endif internal partial class EditorBottomToolbar : VisualElement { #if ENABLE_UXML_TRAITS public class CustomUxmlFactory : UxmlFactory<EditorBottomToolbar, UxmlTraits> { } #endif public void BindElements(ControllerEvents controllerEvents, ViewEvents viewEvents) { var listButton = this.Q<Button>("ListButton"); listButton.clicked += () => viewEvents.onViewTypeUpdate?.Invoke(ViewType.List); var gridButton = this.Q<Button>("GridButton"); gridButton.clicked += () => viewEvents.onViewTypeUpdate?.Invoke(ViewType.Grid); var slider = this.Q<Slider>("SizeSlider"); slider.RegisterValueChangedCallback(evt => viewEvents.onViewSizeUpdate?.Invoke(evt.newValue)); controllerEvents.onViewChanged.AddListener(viewData => slider.SetValueWithoutNotify(viewData.absoluteSize)); viewEvents.onViewSizeUpdate?.Invoke(SpriteLibraryEditorWindow.Settings.viewSize); } } #if ENABLE_UXML_SERIALIZED_DATA [UxmlElement] #endif internal partial class EditorTopToolbar : VisualElement { #if ENABLE_UXML_TRAITS public class CustomUxmlFactory : UxmlFactory<EditorTopToolbar, UxmlTraits> { } #endif ControllerEvents m_ControllerEvents; ViewEvents m_ViewEvents; ObjectField m_ObjectField; ToolbarBreadcrumbs m_Breadcrumbs; ToolbarPopupSearchField m_SearchField; Button m_SaveButton; Button m_RevertButton; Toggle m_AutoSaveToggle; SearchType m_CurrentSearchColumn; SpriteLibraryAsset m_SelectedAsset; public void BindElements(ControllerEvents controllerEvents, ViewEvents viewEvents) { m_ControllerEvents = controllerEvents; m_ViewEvents = viewEvents; m_ControllerEvents.onMainLibraryChanged.AddListener(OnMainAssetChanged); m_ControllerEvents.onSelectedLibrary.AddListener(OnSelectedAssetChanged); m_ControllerEvents.onLibraryDataChanged.AddListener(SetSaveRevertEnabled); this.Q<Image>("SpriteLibraryIcon").image = EditorIconUtility.LoadIconResource("Animation.SpriteLibrary", "ComponentIcons", "ComponentIcons"); var searchController = this.Q("SearchController"); searchController.style.flexGrow = 1; searchController.style.flexDirection = FlexDirection.RowReverse; m_SearchField = new ToolbarPopupSearchField(); m_SearchField.style.flexBasis = 150f; m_SearchField.style.flexGrow = 0; m_SearchField.Q("unity-text-input").style.paddingRight = 0; m_SearchField.menu.AppendAction( EditorGUIUtility.TrTextContent("Category and Label").text, _ => SetSearchType(SearchType.CategoryAndLabel), _ => m_CurrentSearchColumn == SearchType.CategoryAndLabel ? DropdownMenuAction.Status.Checked : DropdownMenuAction.Status.Normal); m_SearchField.menu.AppendAction( EditorGUIUtility.TrTextContent("Category").text, _ => SetSearchType(SearchType.Category), _ => m_CurrentSearchColumn == SearchType.Category ? DropdownMenuAction.Status.Checked : DropdownMenuAction.Status.Normal); m_SearchField.menu.AppendAction( EditorGUIUtility.TrTextContent("Label").text, _ => SetSearchType(SearchType.Label), _ => m_CurrentSearchColumn == SearchType.Label ? DropdownMenuAction.Status.Checked : DropdownMenuAction.Status.Normal); m_SearchField.RegisterValueChangedCallback(evt => viewEvents.onSelectedFilter?.Invoke(evt.newValue)); searchController.Add(m_SearchField); m_ObjectField = this.Q<ObjectField>(); m_ObjectField.allowSceneObjects = false; m_ObjectField.focusable = false; m_ObjectField.objectType = typeof(SpriteLibraryAsset); m_ObjectField.tooltip = TextContent.spriteLibraryMainLibraryTooltip; m_ObjectField.labelElement.style.minWidth = 50; m_ObjectField.labelElement.style.maxWidth = m_ObjectField.labelElement.style.width = 103; m_ObjectField.RegisterValueChangedCallback(OnSelectedMainAsset); m_Breadcrumbs = this.Q<ToolbarBreadcrumbs>(); m_AutoSaveToggle = this.Q<Toggle>(); m_AutoSaveToggle.RegisterValueChangedCallback(OnSelectAutoSave); m_SaveButton = this.Q<Button>("SaveButton"); m_SaveButton.clicked += () => m_ViewEvents.onSave?.Invoke(); m_RevertButton = this.Q<Button>("RevertButton"); m_RevertButton.clicked += () => m_ViewEvents.onRevert?.Invoke(); AutoSaveChanged(SpriteLibraryEditorWindow.Settings.autoSave); } void OnSelectAutoSave(ChangeEvent<bool> evt) { var autoSave = evt.newValue; AutoSaveChanged(autoSave); m_ViewEvents.onToggleAutoSave?.Invoke(autoSave); } void SetSearchType(SearchType searchType) { m_CurrentSearchColumn = searchType; m_ViewEvents.onSelectedFilterType?.Invoke(searchType); } void AutoSaveChanged(bool autoSave) { m_AutoSaveToggle.SetValueWithoutNotify(autoSave); m_SaveButton.style.display = autoSave ? DisplayStyle.None : DisplayStyle.Flex; m_RevertButton.style.display = autoSave ? DisplayStyle.None : DisplayStyle.Flex; } void OnSelectedMainAsset(ChangeEvent<UnityEngine.Object> evt) { var libraryAsset = evt.newValue as SpriteLibraryAsset; m_ViewEvents.onSetMainAsset?.Invoke(libraryAsset); } void OnSelectedAssetChanged(SpriteLibraryAsset selectedAsset) { m_SelectedAsset = selectedAsset; var breadcrumbList = SpriteLibrarySourceAssetImporter.GetAssetParentChain(selectedAsset); UpdateBreadCrumbs(breadcrumbList); m_ObjectField.SetValueWithoutNotify(SpriteLibrarySourceAssetImporter.GetAssetParent(selectedAsset)); SetSaveRevertEnabled(false); } void OnMainAssetChanged(SpriteLibraryAsset mainAsset) { var breadcrumbList = SpriteLibrarySourceAssetImporter.GetAssetParentChain(mainAsset); if (mainAsset != null) breadcrumbList.Insert(0, mainAsset); UpdateBreadCrumbs(breadcrumbList); m_ObjectField.SetValueWithoutNotify(mainAsset); } void UpdateBreadCrumbs(List<SpriteLibraryAsset> breadcrumbList) { m_Breadcrumbs.Clear(); if (breadcrumbList.Count > 0) { for (var i = breadcrumbList.Count; i-- > 0;) { var asset = breadcrumbList[i]; m_Breadcrumbs.PushItem(asset.name, () => OnBreadcrumbClicked(asset)); } } if (m_SelectedAsset != null) m_Breadcrumbs.PushItem(m_SelectedAsset.name, () => OnBreadcrumbClicked(m_SelectedAsset)); } static void OnBreadcrumbClicked(SpriteLibraryAsset asset) { Selection.objects = new UnityEngine.Object[] { asset }; EditorGUIUtility.PingObject(asset); } void SetSaveRevertEnabled(bool toggleEnabled) { m_SaveButton.SetEnabled(toggleEnabled); m_RevertButton.SetEnabled(toggleEnabled); } } #if ENABLE_UXML_SERIALIZED_DATA [UxmlElement] #endif internal partial class EditorTabHeader : VisualElement { #if ENABLE_UXML_TRAITS public class CustomUxmlFactory : UxmlFactory<EditorTabHeader, UxmlTraits> { } #endif } }