Initial commit

This commit is contained in:
AbstractConcept 2022-09-13 00:36:34 -05:00
commit 3c7cc0c973
8391 changed files with 704313 additions and 0 deletions

View file

@ -0,0 +1,190 @@
using System;
using UnityEditor.U2D.Layout;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.U2D.Animation
{
internal class BoneReparentToolController : BoneTreeWidgetController
{
public BoneReparentToolController(IBoneTreeViewModel model, SkinningEvents eventSystem) : base(model, eventSystem)
{}
public override bool CanDrag()
{
m_SkinningEvents.boneVisibility.Invoke("drag");
return (m_Model.hasCharacter && m_Model.mode == SkinningMode.Character) ||
(!m_Model.hasCharacter && m_Model.mode == SkinningMode.SpriteSheet);
}
public override bool CanRename()
{
m_SkinningEvents.boneVisibility.Invoke("rename");
return true;
}
}
internal class BoneReparentToolModel : BoneTreeWidgetModel
{
public BoneReparentToolModel(SkinningCache cache, IBoneVisibilityToolView view)
{
m_SkinningCache = cache;
m_View = view;
m_Data = skinningCache.CreateCache<BoneVisibilityToolData>();
}
}
internal class BoneReparentTool : SkeletonToolWrapper
{
BoneReparentToolWindow m_View;
BoneReparentToolModel m_Model;
private BoneReparentToolController m_Controller;
public override void Initialize(LayoutOverlay layout)
{
if (m_View == null)
{
m_View = BoneReparentToolWindow.CreateFromUXML();
}
m_Model = new BoneReparentToolModel(skinningCache, m_View);
m_Controller = new BoneReparentToolController(m_Model, skinningCache.events);
m_View.GetController = () => m_Controller;
m_View.GetModel = () => m_Model;
layout.rightOverlay.Add(m_View);
m_View.SetHiddenFromLayout(true);
}
protected override void OnActivate()
{
m_View.SetHiddenFromLayout(false);
m_Controller.Activate();
skeletonTool.Activate();
}
protected override void OnDeactivate()
{
m_View.SetHiddenFromLayout(true);
m_Controller.Deactivate();
skeletonTool.Deactivate();
}
protected override void OnGUI()
{
skeletonTool.mode = mode;
skeletonTool.editBindPose = editBindPose;
skeletonTool.DoGUI();
}
}
internal class BoneReparentToolWindow : VisualElement, IBoneVisibilityToolView
{
public class CustomUxmlFactory : UxmlFactory<BoneReparentToolWindow, UxmlTraits> {}
BoneReparentToolView m_ToolView;
public Func<IBoneTreeViewModel> GetModel = () => null;
public Func<BoneTreeWidgetController> GetController = () => null;
static internal BoneReparentToolWindow CreateFromUXML()
{
var visualTree = ResourceLoader.Load<VisualTreeAsset>("SkinningModule/BoneReparentWindow.uxml");
var ve = visualTree.CloneTree().Q("BoneReparentToolWindow") as BoneReparentToolWindow;
ve.BindElements();
return ve;
}
internal void BindElements()
{
m_ToolView = this.Q<BoneReparentToolView>();
m_ToolView.GetModel = InternalGetModel;
m_ToolView.GetController = InternalGetController;
this.styleSheets.Add(ResourceLoader.Load<StyleSheet>("SkinningModule/BoneReparentStyle.uss"));
}
IBoneTreeViewModel InternalGetModel()
{
return GetModel();
}
BoneTreeWidgetController InternalGetController()
{
return GetController();
}
public void OnBoneSelectionChange(SkeletonSelection skeleton)
{
((IBoneVisibilityToolView)toolView).OnBoneSelectionChange(skeleton);
}
public void OnBoneExpandedChange(BoneCache[] bones)
{
((IBoneVisibilityToolView)toolView).OnBoneExpandedChange(bones);
}
public void OnBoneNameChanged(BoneCache bone)
{
((IBoneVisibilityToolView)toolView).OnBoneNameChanged(bone);
}
public void OnSelectionChange(SkeletonCache skeleton)
{
((IBoneVisibilityToolView)toolView).OnSelectionChange(skeleton);
}
BoneReparentToolView toolView { get {return m_ToolView; } }
public void Deactivate()
{
toolView.Deactivate();
}
}
internal class BoneReparentToolView : BoneVisibilityToolView
{
public class CustomUxmlFactory : UxmlFactory<BoneReparentToolView, CustomUxmlTraits> {}
public class CustomUxmlTraits : UxmlTraits {}
protected override VisibilityToolColumnHeader SetupToolColumnHeader()
{
var columns = new MultiColumnHeaderState.Column[3];
columns[0] = new MultiColumnHeaderState.Column
{
headerContent = VisibilityTreeViewBase.VisibilityIconStyle.visibilityOnIcon,
headerTextAlignment = TextAlignment.Center,
width = 32,
minWidth = 32,
maxWidth = 32,
autoResize = false,
allowToggleVisibility = true
};
columns[1] = new MultiColumnHeaderState.Column
{
headerContent = EditorGUIUtility.TrTextContent("Bone"),
headerTextAlignment = TextAlignment.Center,
width = 170,
minWidth = 130,
autoResize = true,
allowToggleVisibility = false
};
columns[2] = new MultiColumnHeaderState.Column
{
headerContent = EditorGUIUtility.TrTextContent("Depth"),
headerTextAlignment = TextAlignment.Center,
width = 40,
minWidth = 40,
maxWidth = 40,
autoResize = false,
allowToggleVisibility = true
};
var multiColumnHeaderState = new MultiColumnHeaderState(columns);
return new VisibilityToolColumnHeader(multiColumnHeaderState)
{
GetAllVisibility = GetAllVisibility,
SetAllVisibility = SetAllVisibility,
canSort = false,
height = 20,
visibilityColumn = 0
};
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a660ba45386a23843a274d00b171e0fc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,280 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.IMGUI.Controls;
namespace UnityEditor.U2D.Animation
{
internal class BoneTreeWidgetController
{
protected IBoneTreeViewModel m_Model;
protected SkinningEvents m_SkinningEvents;
public BoneTreeWidgetController(IBoneTreeViewModel model, SkinningEvents eventSystem)
{
m_Model = model;
m_SkinningEvents = eventSystem;
}
public void Activate()
{
SetupSkeleton();
m_SkinningEvents.selectedSpriteChanged.AddListener(OnSelectionChange);
m_SkinningEvents.skinningModeChanged.AddListener(OnSkinningModuleModeChanged);
m_SkinningEvents.boneSelectionChanged.AddListener(OnBoneSelectionChanged);
m_SkinningEvents.boneNameChanged.AddListener(OnBoneNameChanged);
m_SkinningEvents.skeletonTopologyChanged.AddListener(SkeletonTopologyChanged);
}
public void Deactivate()
{
m_SkinningEvents.selectedSpriteChanged.RemoveListener(OnSelectionChange);
m_SkinningEvents.skinningModeChanged.RemoveListener(OnSkinningModuleModeChanged);
m_SkinningEvents.boneSelectionChanged.RemoveListener(OnBoneSelectionChanged);
m_SkinningEvents.boneNameChanged.RemoveListener(OnBoneNameChanged);
m_SkinningEvents.skeletonTopologyChanged.RemoveListener(SkeletonTopologyChanged);
if (m_Model.view != null)
m_Model.view.Deactivate();
}
private void OnSelectionChange(SpriteCache sprite)
{
SetupSkeleton();
m_Model.SetAllVisibility(null, true);
}
private void OnBoneSelectionChanged()
{
m_Model.view.OnBoneSelectionChange(m_Model.GetBoneSelection());
}
private void OnBoneNameChanged(BoneCache bone)
{
m_Model.view.OnBoneNameChanged(bone);
}
private void OnSkinningModuleModeChanged(SkinningMode mode)
{
SetupSkeleton();
m_Model.SetAllVisibility(null, true);
}
private void SetupSkeleton()
{
m_Model.view.OnSelectionChange(m_Model.GetSelectedSkeleton());
m_Model.view.OnBoneExpandedChange(m_Model.GetExpandedBones());
m_Model.view.OnBoneSelectionChange(m_Model.GetBoneSelection());
}
public void SetAllVisibility(bool visibility)
{
var skeleton = m_Model.GetSelectedSkeleton();
if (skeleton != null)
{
using (m_Model.UndoScope(TextContent.boneVisibility))
{
m_Model.SetAllVisibility(skeleton, visibility);
}
}
}
private void SkeletonTopologyChanged(SkeletonCache skeleton)
{
m_Model.view.OnSelectionChange(skeleton);
}
public List<TreeViewItem> BuildTreeView()
{
var rows = new List<TreeViewItem>();
var skeleton = m_Model.GetSelectedSkeleton();
if (skeleton != null)
{
var bones = skeleton.bones;
var children = bones.Where(x => x.parentBone == null).ToArray();
Array.Sort(children, (a, b) => a.siblingIndex.CompareTo(b.siblingIndex));
foreach (var bone in children)
AddTreeViewItem(rows, bone, bones, 0);
}
return rows;
}
private static void AddTreeViewItem(IList<TreeViewItem> rows, BoneCache bone, BoneCache[] bones, int depth)
{
var item = new TreeViewItemBase<BoneCache>(bone.GetInstanceID(), depth, bone.name, bone);
rows.Add(item);
var children = bones.Where(x => x.parentBone == bone).ToArray();
Array.Sort(children, (a, b) => a.siblingIndex.CompareTo(b.siblingIndex));
foreach (var childBone in children)
AddTreeViewItem(rows, childBone, bones, depth + 1);
}
public List<int> GetIDsToExpand(BoneCache[] bones)
{
var result = new List<int>();
if (bones != null)
{
foreach (var bone in bones)
{
if (bone != null)
{
var parent = bone.parentBone;
while (parent != null)
{
int parentId = parent.GetInstanceID();
result.Add(parentId);
parent = parent.parentBone;
}
}
}
}
return result;
}
public int[] GetIDsToSelect(BoneCache[] bones)
{
return bones == null ? new int[0] : Array.ConvertAll(bones, x => x != null ? x.GetInstanceID() : 0);
}
public void SelectBones(IList<int> selectedIds, IList<TreeViewItem> items)
{
var selectedBones = items.Where(x => selectedIds.Contains(x.id)).Select(y => ((TreeViewItemBase<BoneCache>)y).customData).ToArray();
using (m_Model.UndoScope(TextContent.boneSelection))
{
m_Model.SelectBones(selectedBones);
m_SkinningEvents.boneSelectionChanged.Invoke();
}
}
public void ExpandBones(IList<int> expandedIds, IList<TreeViewItem> items)
{
var expandedBones = items.Where(x => expandedIds.Contains(x.id)).Select(y => ((TreeViewItemBase<BoneCache>)y).customData).ToArray();
using (m_Model.UndoScope(TextContent.expandBones))
{
m_Model.SetExpandedBones(expandedBones);
}
}
public bool GetTreeItemVisibility(TreeViewItemBase<BoneCache> item)
{
return m_Model.GetVisibility(item.customData);
}
public void SetTreeItemVisibility(TreeViewItemBase<BoneCache> item, bool visible, bool includeChildren)
{
var bone = item.customData;
if (bone != null && bone.isVisible != visible)
{
using (m_Model.UndoScope(TextContent.visibilityChange))
{
m_Model.SetVisibility(item.customData, visible);
if (includeChildren)
{
// toggle all children as well
SetChildrenVisibility(item, visible);
}
}
}
}
void SetChildrenVisibility(TreeViewItemBase<BoneCache> bone, bool visible)
{
if (bone.children == null)
return;
foreach (var childBone in bone.children)
{
var cb = childBone as TreeViewItemBase<BoneCache>;
SetChildrenVisibility(cb, visible);
m_Model.SetVisibility(cb.customData, visible);
}
}
public int GetTreeItemDepthValue(TreeViewItemBase<BoneCache> bone)
{
return m_Model.GetDepth(bone.customData);
}
public void SetTreeItemDepthValue(TreeViewItemBase<BoneCache> bone, int value)
{
if (bone != null && bone.customData != null)
{
using (m_Model.UndoScope(TextContent.boneDepth))
{
m_Model.SetDepth(bone.customData, value);
m_SkinningEvents.boneNameChanged.Invoke(bone.customData);
}
}
}
public void SetTreeViewBoneName(IList<TreeViewItem> items, BoneCache bone)
{
var treeBone = items.FirstOrDefault(x => ((TreeViewItemBase<BoneCache>)x).customData == bone);
if (treeBone != null)
treeBone.displayName = bone.name;
}
public void TreeViewItemRename(IList<TreeViewItem> rows, int itemID, string newName)
{
var item = rows.FirstOrDefault(x => x.id == itemID) as TreeViewItemBase<BoneCache>;
if (item == null)
return;
if (item.customData != null && item.customData.name != newName && !string.IsNullOrEmpty(newName)
&& !string.IsNullOrWhiteSpace(newName))
{
item.displayName = newName;
using (m_Model.UndoScope(TextContent.boneName))
{
m_Model.SetName(item.customData, newName);
m_SkinningEvents.boneNameChanged.Invoke(item.customData);
}
}
}
public bool CanReparent(TreeViewItemBase<BoneCache> parent, List<TreeViewItem> draggedItems)
{
TreeViewItemBase<BoneCache> currentParent = parent;
while (currentParent != null)
{
if (draggedItems.Contains(currentParent))
return false;
currentParent = currentParent.parent as TreeViewItemBase<BoneCache>;
}
return true;
}
public void ReparentItems(TreeViewItemBase<BoneCache> newParent, List<TreeViewItem> draggedItems, int insertAtIndex)
{
if ((m_Model.hasCharacter && m_Model.mode != SkinningMode.Character) ||
(!m_Model.hasCharacter && m_Model.mode == SkinningMode.Character))
return;
var parent = newParent != null ? newParent.customData : null;
using (m_Model.UndoScope(TextContent.setParentBone))
{
for (var i = draggedItems.Count - 1; i >= 0; --i)
{
var bone = ((TreeViewItemBase<BoneCache>)draggedItems[i]).customData;
m_Model.SetBoneParent(parent, bone, insertAtIndex);
m_SkinningEvents.skeletonTopologyChanged.Invoke(bone.skeleton);
}
}
}
public virtual bool CanDrag()
{
m_SkinningEvents.boneVisibility.Invoke("drag");
return false;
}
public virtual bool CanRename()
{
m_SkinningEvents.boneVisibility.Invoke("rename");
return false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40cebb2c3989f5844a7cbdc20bb68bdf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,175 @@
using System;
using UnityEngine;
namespace UnityEditor.U2D.Animation
{
internal class BoneVisibilityToolData : CacheObject
{
[SerializeField]
bool m_AllVisibility = true;
bool m_PreviousVisibility = true;
public bool allVisibility
{
get { return m_AllVisibility; }
set { m_AllVisibility = value; }
}
public bool previousVisiblity
{
get { return m_PreviousVisibility; }
set { m_PreviousVisibility = value; }
}
}
internal class BoneTreeWidgetModel : IBoneTreeViewModel
{
protected SkinningCache m_SkinningCache;
protected IBoneVisibilityToolView m_View;
protected BoneVisibilityToolData m_Data;
public SkinningCache skinningCache
{
get { return m_SkinningCache; }
}
public IBoneVisibilityToolView view
{
get { return m_View; }
}
public virtual bool GetAllVisibility()
{
return m_Data.allVisibility;
}
public SkeletonSelection GetBoneSelection()
{
return skinningCache.skeletonSelection;
}
public BoneCache[] GetExpandedBones()
{
return skinningCache.GetExpandedBones();
}
public int GetDepth(BoneCache bone)
{
return (int)bone.depth;
}
public SkeletonCache GetSelectedSkeleton()
{
return skinningCache.GetEffectiveSkeleton(skinningCache.selectedSprite);
}
public bool GetVisibility(BoneCache bone)
{
return bone.isVisible;
}
public void SelectBones(BoneCache[] bones)
{
skinningCache.skeletonSelection.elements = bones.ToCharacterIfNeeded();
}
public void SetExpandedBones(BoneCache[] bones)
{
skinningCache.BoneExpansionChanged(bones);
}
public virtual void SetAllVisibility(SkeletonCache skeleton, bool visibility)
{
m_Data.allVisibility = visibility;
SetAllBoneVisibility(skeleton, visibility);
UpdateVisibilityFromPersistentState();
}
public static void SetAllBoneVisibility(SkeletonCache skeleton, bool visibility)
{
if (skeleton != null)
{
foreach (var bone in skeleton.bones)
bone.isVisible = visibility;
}
}
public void SetBoneParent(BoneCache newParent, BoneCache bone, int insertAtIndex)
{
TransformCache parent = newParent;
if (newParent == null)
parent = bone.skeleton;
skinningCache.RestoreBindPose();
bone.SetParent(parent, true);
if (insertAtIndex == -1)
insertAtIndex = parent.ChildCount;
bone.siblingIndex = insertAtIndex;
bone.SetDefaultPose();
}
public void SetDepth(BoneCache bone, int depth)
{
var characterBone = bone.ToCharacterIfNeeded();
characterBone.depth = depth;
if (characterBone != bone || skinningCache.mode == SkinningMode.Character)
skinningCache.SyncSpriteSheetSkeletons();
skinningCache.events.boneDepthChanged.Invoke(bone);
}
public void SetName(BoneCache bone, string name)
{
var characterBone = bone.ToCharacterIfNeeded();
characterBone.name = name;
if (characterBone != bone || skinningCache.mode == SkinningMode.Character)
{
skinningCache.SyncSpriteSheetSkeletons();
}
}
public void SetVisibility(BoneCache bone, bool visibility)
{
bone.isVisible = visibility;
UpdateVisibilityFromPersistentState();
}
public UndoScope UndoScope(string value)
{
return skinningCache.UndoScope(value);
}
private void UpdateVisibilityFromPersistentState()
{
skinningCache.BoneVisibilityChanged(GetSelectedSkeleton());
}
public bool hasCharacter {get { return skinningCache.hasCharacter; } }
public SkinningMode mode {get { return skinningCache.mode; } }
}
internal interface IBoneTreeViewModel
{
void SetVisibility(BoneCache bone, bool visibility);
bool GetVisibility(BoneCache bone);
void SetName(BoneCache bone, string name);
void SetBoneParent(BoneCache newParent, BoneCache bone, int insertAtIndex);
int GetDepth(BoneCache bone);
void SetDepth(BoneCache bone, int depth);
void SetAllVisibility(SkeletonCache skeleton, bool visibility);
bool GetAllVisibility();
void SelectBones(BoneCache[] bones);
void SetExpandedBones(BoneCache[] bones);
IBoneVisibilityToolView view { get; }
SkeletonSelection GetBoneSelection();
BoneCache[] GetExpandedBones();
SkeletonCache GetSelectedSkeleton();
bool hasCharacter { get; }
SkinningMode mode { get; }
UndoScope UndoScope(string value);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dc4f326c25da1c048a6365f4f5c7198e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,350 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.IMGUI.Controls;
using System;
using System.Linq;
using UnityEngine.UIElements;
namespace UnityEditor.U2D.Animation
{
internal class BoneVisibilityTool : BoneTreeWidgetModel, IVisibilityTool
{
private BoneTreeWidgetController m_Controller;
VisualElement IVisibilityTool.view { get { return (VisualElement)m_View; } }
public string name { get { return "Bone"; } }
public bool isAvailable
{
get { return true; }
}
public BoneVisibilityTool(SkinningCache s)
{
m_SkinningCache = s;
}
public void Setup()
{
m_Data = skinningCache.CreateCache<BoneVisibilityToolData>();
m_Controller = new BoneReparentToolController(this, skinningCache.events);//new BoneTreeWidgetController(this, skinningCache.events);
m_View = new BoneReparentToolView()
{
GetModel = () => this,
GetController = () => m_Controller
};
}
public void Dispose()
{}
public void Activate()
{
m_Controller.Activate();
if (m_Data.previousVisiblity != m_Data.allVisibility)
{
m_Data.previousVisiblity = m_Data.allVisibility;
}
}
public void Deactivate()
{
m_Controller.Deactivate();
}
public void SetAvailabilityChangeCallback(Action callback)
{}
}
internal class BoneVisibilityToolView : VisibilityToolViewBase, IBoneVisibilityToolView
{
public Func<BoneTreeWidgetController> GetController = () => null;
public Func<IBoneTreeViewModel> GetModel = () => null;
public BoneVisibilityToolView()
{
m_TreeView = new BoneTreeView(m_TreeViewState, SetupToolColumnHeader())
{
GetController = InternalGetController
};
SetupSearchField();
}
protected virtual VisibilityToolColumnHeader SetupToolColumnHeader()
{
var columns = new MultiColumnHeaderState.Column[2];
columns[0] = new MultiColumnHeaderState.Column
{
headerContent = VisibilityTreeViewBase.VisibilityIconStyle.visibilityOnIcon,
headerTextAlignment = TextAlignment.Center,
width = 32,
minWidth = 32,
maxWidth = 32,
autoResize = false,
allowToggleVisibility = true
};
columns[1] = new MultiColumnHeaderState.Column
{
headerContent = EditorGUIUtility.TrTextContent(TextContent.bone),
headerTextAlignment = TextAlignment.Center,
width = 200,
minWidth = 130,
autoResize = true,
allowToggleVisibility = false
};
var multiColumnHeaderState = new MultiColumnHeaderState(columns);
return new VisibilityToolColumnHeader(multiColumnHeaderState)
{
GetAllVisibility = GetAllVisibility,
SetAllVisibility = SetAllVisibility,
canSort = false,
height = 20,
visibilityColumn = 0
};
}
BoneTreeWidgetController InternalGetController()
{
return GetController();
}
protected void SetAllVisibility(bool visibility)
{
GetController().SetAllVisibility(visibility);
}
protected bool GetAllVisibility()
{
return GetModel().GetAllVisibility();
}
public void OnSelectionChange(SkeletonCache skeleton)
{
((BoneTreeView)m_TreeView).SetupHierarchy();
}
public void OnBoneSelectionChange(SkeletonSelection bones)
{
((BoneTreeView)m_TreeView).OnBoneSelectionChanged(bones);
}
public void OnBoneExpandedChange(BoneCache[] bones)
{
((BoneTreeView)m_TreeView).OnBoneExpandedChanged(bones);
}
public void OnBoneNameChanged(BoneCache bone)
{
((BoneTreeView)m_TreeView).OnBoneNameChanged(bone);
}
public void Deactivate()
{
if (m_TreeView.HasSelection())
m_TreeView.EndRename();
}
}
class BoneTreeView : VisibilityTreeViewBase
{
public Func<BoneTreeWidgetController> GetController = () => null;
public BoneTreeView(TreeViewState treeViewState, MultiColumnHeader columnHeader)
: base(treeViewState, columnHeader)
{
columnIndexForTreeFoldouts = 1;
ReloadView();
}
public void SetupHierarchy()
{
ReloadView();
}
private void ReloadView()
{
Reload();
}
public void OnBoneSelectionChanged(SkeletonSelection boneSelection)
{
var bones = boneSelection.elements.ToSpriteSheetIfNeeded();
var ids = GetController().GetIDsToSelect(bones);
var result = GetController().GetIDsToExpand(bones);
var expandIds = GetExpanded().ToList();
if (result.Count > 0)
expandIds = expandIds.Union(result).ToList();
SetExpanded(expandIds);
SetSelection(ids);
}
public void OnBoneExpandedChanged(BoneCache[] bones)
{
var expandIds = GetController().GetIDsToSelect(bones);
if (expandIds.Length == 0)
return;
SetExpanded(expandIds.Union(GetExpanded()).ToList());
}
public void OnBoneNameChanged(BoneCache bone)
{
GetController().SetTreeViewBoneName(GetRows(), bone);
}
protected override void SelectionChanged(IList<int> selectedIds)
{
GetController().SelectBones(selectedIds, GetRows());
}
protected override void ExpandedStateChanged()
{
GetController().ExpandBones(GetExpanded(), GetRows());
}
protected override float GetCustomRowHeight(int row, TreeViewItem item)
{
return EditorGUIUtility.singleLineHeight * 1.1f;
}
void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
{
CenterRectUsingSingleLineHeight(ref cellRect);
switch (column)
{
case 0:
DrawVisibilityCell(cellRect, item);
break;
case 1:
DrawNameCell(cellRect, item, ref args);
break;
case 2:
DrawDepthCell(cellRect, item);
break;
}
}
void DrawDepthCell(Rect cellRect, TreeViewItem item)
{
var boneItemView = item as TreeViewItemBase<BoneCache>;
int depth = GetController().GetTreeItemDepthValue(boneItemView);
const int width = 30;
cellRect.height = EditorGUIUtility.singleLineHeight;
cellRect.x += (cellRect.width - width) * 0.5f;
cellRect.width = width;
EditorGUI.BeginChangeCheck();
depth = EditorGUI.IntField(cellRect, depth);
if (EditorGUI.EndChangeCheck())
GetController().SetTreeItemDepthValue(boneItemView, depth);
}
void DrawVisibilityCell(Rect cellRect, TreeViewItem item)
{
GUIStyle style = MultiColumnHeader.DefaultStyles.columnHeaderCenterAligned;
EditorGUI.BeginChangeCheck();
var boneItemView = item as TreeViewItemBase<BoneCache>;
bool visible = GetController().GetTreeItemVisibility(boneItemView);
visible = GUI.Toggle(cellRect, visible, visible ? VisibilityIconStyle.visibilityOnIcon : VisibilityIconStyle.visibilityOffIcon, style);
if (EditorGUI.EndChangeCheck())
{
GetController().SetTreeItemVisibility(boneItemView, visible, Event.current.alt);
}
}
void DrawNameCell(Rect cellRect, TreeViewItem item, ref RowGUIArgs args)
{
args.rowRect = cellRect;
base.RowGUI(args);
}
protected override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item)
{
Rect cellRect = GetCellRectForTreeFoldouts(rowRect);
CenterRectUsingSingleLineHeight(ref cellRect);
return base.GetRenameRect(cellRect, row, item);
}
protected override void RowGUI(RowGUIArgs args)
{
var item = args.item;
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
{
CellGUI(args.GetCellRect(i), item, args.GetColumn(i), ref args);
}
}
protected override TreeViewItem BuildRoot()
{
var root = new TreeViewItem {id = 0, depth = -1, displayName = "Root"};
List<TreeViewItem> rows = GetController() != null ? GetController().BuildTreeView() : new List<TreeViewItem>();
SetupParentsAndChildrenFromDepths(root, rows);
return root;
}
protected override bool CanRename(TreeViewItem item)
{
return GetController().CanRename();
}
protected override void RenameEnded(RenameEndedArgs args)
{
var rows = GetRows();
GetController().TreeViewItemRename(rows, args.itemID, args.newName);
base.RenameEnded(args);
}
// dragging
const string k_GenericDragID = "GenericDragColumnDragging";
protected override bool CanStartDrag(CanStartDragArgs args)
{
return true;
}
protected override void SetupDragAndDrop(SetupDragAndDropArgs args)
{
if (GetController().CanDrag() && !hasSearch)
{
DragAndDrop.PrepareStartDrag();
var draggedRows = GetRows().Where(item => args.draggedItemIDs.Contains(item.id)).ToList();
DragAndDrop.SetGenericData(k_GenericDragID, draggedRows);
DragAndDrop.objectReferences = new UnityEngine.Object[] {}; // this IS required for dragging to work
string title = draggedRows.Count == 1 ? draggedRows[0].displayName : "< Multiple >";
DragAndDrop.StartDrag(title);
}
}
protected override DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args)
{
// Check if we can handle the current drag data (could be dragged in from other areas/windows in the editor)
var draggedRows = DragAndDrop.GetGenericData(k_GenericDragID) as List<TreeViewItem>;
if (draggedRows == null)
return DragAndDropVisualMode.None;
// Parent item is null when dragging outside any tree view items.
switch (args.dragAndDropPosition)
{
case DragAndDropPosition.UponItem:
case DragAndDropPosition.OutsideItems:
case DragAndDropPosition.BetweenItems:
{
var newParent = args.parentItem as TreeViewItemBase<BoneCache>;
bool validDrag = false;
validDrag = GetController().CanReparent(newParent, draggedRows);
if (args.performDrop && validDrag)
{
GetController().ReparentItems(newParent, draggedRows, args.insertAtIndex);
Reload();
var selectedIDs = draggedRows.ConvertAll(b => b.id);
SetSelection(selectedIDs, TreeViewSelectionOptions.RevealAndFrame);
SelectionChanged(selectedIDs);
}
return validDrag ? DragAndDropVisualMode.Move : DragAndDropVisualMode.None;
}
}
return DragAndDropVisualMode.None;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0e8a5f39ab443849ac34497669e976f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,11 @@
namespace UnityEditor.U2D.Animation
{
internal interface IBoneVisibilityToolView
{
void OnBoneSelectionChange(SkeletonSelection skeleton);
void OnBoneExpandedChange(BoneCache[] bones);
void OnBoneNameChanged(BoneCache bone);
void OnSelectionChange(SkeletonCache skeleton);
void Deactivate();
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc0f7df10f714e0458bbe6f652412bda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,345 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.IMGUI.Controls;
using System;
using System.Linq;
using UnityEngine.UIElements;
namespace UnityEditor.U2D.Animation
{
internal class MeshVisibilityTool : IVisibilityTool
{
private MeshVisibilityToolView m_View;
private MeshVisibilityToolModel m_Model;
private SkinningCache m_SkinningCache;
public SkinningCache skinningCache { get { return m_SkinningCache; } }
public MeshVisibilityTool(SkinningCache s)
{
m_SkinningCache = s;
}
public void Setup()
{
m_Model = skinningCache.CreateCache<MeshVisibilityToolModel>();
m_View = new MeshVisibilityToolView(skinningCache)
{
GetModel = () => m_Model,
SetAllVisibility = SetAllVisibility,
GetAllVisibility = GetAllVisibility
};
}
public void Dispose()
{
}
public VisualElement view { get { return m_View; } }
public string name { get { return "Mesh"; } }
public void Activate()
{
skinningCache.events.selectedSpriteChanged.AddListener(OnSelectionChange);
skinningCache.events.skinningModeChanged.AddListener(OnViewModeChanged);
OnViewModeChanged(skinningCache.mode);
if (m_Model.previousVisiblity != m_Model.allVisibility)
{
SetAllMeshVisibility();
m_Model.previousVisiblity = m_Model.allVisibility;
}
}
public void Deactivate()
{
skinningCache.events.selectedSpriteChanged.RemoveListener(OnSelectionChange);
skinningCache.events.skinningModeChanged.RemoveListener(OnViewModeChanged);
}
public bool isAvailable
{
get { return false; }
}
public void SetAvailabilityChangeCallback(Action callback)
{}
private void OnViewModeChanged(SkinningMode characterMode)
{
if (characterMode == SkinningMode.Character)
{
m_View.Setup(skinningCache.GetSprites());
}
else
{
m_View.Setup(new[] { skinningCache.selectedSprite });
}
}
private void OnSelectionChange(SpriteCache sprite)
{
OnViewModeChanged(skinningCache.mode);
SetAllMeshVisibility();
}
void SetAllVisibility(bool visibility)
{
using (skinningCache.UndoScope(TextContent.meshVisibility))
{
m_Model.allVisibility = visibility;
SetAllMeshVisibility();
}
}
void SetAllMeshVisibility()
{
SpriteCache[] sprites;
if (skinningCache.mode == SkinningMode.Character)
sprites = skinningCache.GetSprites();
else
sprites = new[] { skinningCache.selectedSprite };
foreach (var spr in sprites)
{
if (spr != null)
m_Model.SetMeshVisibility(spr, m_Model.allVisibility);
}
}
bool GetAllVisibility()
{
return m_Model.allVisibility;
}
}
internal class MeshVisibilityToolModel : SkinningObject
{
[SerializeField]
bool m_AllVisibility = true;
bool m_PreviousVisibility = true;
public bool allVisibility
{
get {return m_AllVisibility; }
set { m_AllVisibility = value; }
}
public void SetMeshVisibility(SpriteCache sprite, bool visibility)
{
}
public bool GetMeshVisibility(SpriteCache sprite)
{
return false;
}
public bool ShouldDisable(SpriteCache sprite)
{
var mesh = sprite.GetMesh();
return mesh == null || mesh.vertices.Count == 0;
}
public bool previousVisiblity
{
get { return m_PreviousVisibility; }
set { m_PreviousVisibility = value; }
}
}
internal class MeshVisibilityToolView : VisibilityToolViewBase
{
public Func<MeshVisibilityToolModel> GetModel = () => null;
public Action<bool> SetAllVisibility = (b) => {};
public Func<bool> GetAllVisibility = () => true;
public SkinningCache skinningCache { get; set; }
public MeshVisibilityToolView(SkinningCache s)
{
skinningCache = s;
var columns = new MultiColumnHeaderState.Column[2];
columns[0] = new MultiColumnHeaderState.Column
{
headerContent = EditorGUIUtility.TrTextContent(TextContent.name),
headerTextAlignment = TextAlignment.Center,
width = 200,
minWidth = 130,
autoResize = true,
allowToggleVisibility = false
};
columns[1] = new MultiColumnHeaderState.Column
{
headerContent = new GUIContent(EditorGUIUtility.FindTexture("visibilityOn")),
headerTextAlignment = TextAlignment.Center,
width = 32,
minWidth = 32,
maxWidth = 32,
autoResize = false,
allowToggleVisibility = true
};
var multiColumnHeaderState = new MultiColumnHeaderState(columns);
var multiColumnHeader = new VisibilityToolColumnHeader(multiColumnHeaderState)
{
GetAllVisibility = InternalGetAllVisibility,
SetAllVisibility = InternalSetAllVisibility,
canSort = false,
height = 20,
visibilityColumn = 1
};
m_TreeView = new MeshTreeView(m_TreeViewState, multiColumnHeader)
{
GetModel = InternalGetModel
};
SetupSearchField();
}
MeshVisibilityToolModel InternalGetModel()
{
return GetModel();
}
public void Setup(SpriteCache[] sprites)
{
((MeshTreeView)m_TreeView).Setup(sprites);
((MeshTreeView)m_TreeView).SetSelection(skinningCache.selectedSprite);
}
bool InternalGetAllVisibility()
{
return GetAllVisibility();
}
void InternalSetAllVisibility(bool visibility)
{
SetAllVisibility(visibility);
}
}
class MeshTreeView : VisibilityTreeViewBase
{
private List<SpriteCache> m_Sprites = new List<SpriteCache>();
public MeshTreeView(TreeViewState treeViewState, MultiColumnHeader header)
: base(treeViewState, header)
{
this.showAlternatingRowBackgrounds = true;
this.useScrollView = true;
Reload();
}
public Func<MeshVisibilityToolModel> GetModel = () => null;
public void Setup(SpriteCache[] sprites)
{
m_Sprites.Clear();
m_Sprites.AddRange(sprites);
Reload();
}
private static TreeViewItem CreateTreeViewItem(SpriteCache part)
{
return new TreeViewItemBase<SpriteCache>(part.GetInstanceID(), -1, part.name, part);
}
private void AddTreeViewItem(IList<TreeViewItem> rows, SpriteCache part)
{
if (string.IsNullOrEmpty(searchString) || part.name.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
{
var item = CreateTreeViewItem(part);
rows.Add(item);
rootItem.AddChild(item);
}
}
private void CellGUI(Rect cellRect, TreeViewItem item, int column, ref RowGUIArgs args)
{
CenterRectUsingSingleLineHeight(ref cellRect);
switch (column)
{
case 0:
DrawNameCell(cellRect, item, ref args);
break;
case 1:
DrawVisibilityCell(cellRect, item);
break;
}
}
private void DrawVisibilityCell(Rect cellRect, TreeViewItem item)
{
GUIStyle style = MultiColumnHeader.DefaultStyles.columnHeaderCenterAligned;
var itemView = item as TreeViewItemBase<SpriteCache>;
var shouldDisable = GetModel().ShouldDisable(itemView.customData);
using (new EditorGUI.DisabledScope(shouldDisable))
{
EditorGUI.BeginChangeCheck();
bool visible = GetModel().GetMeshVisibility(itemView.customData);
visible = GUI.Toggle(cellRect, visible, visible ? VisibilityIconStyle.visibilityOnIcon : VisibilityIconStyle.visibilityOffIcon, style);
if (EditorGUI.EndChangeCheck())
GetModel().SetMeshVisibility(itemView.customData, visible);
}
}
private void DrawNameCell(Rect cellRect, TreeViewItem item, ref RowGUIArgs args)
{
args.rowRect = cellRect;
base.RowGUI(args);
}
protected override void RowGUI(RowGUIArgs args)
{
var item = args.item;
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
{
CellGUI(args.GetCellRect(i), item, args.GetColumn(i), ref args);
}
}
protected override void SelectionChanged(IList<int> selectedIds)
{
SpriteCache newSelected = null;
if (selectedIds.Count > 0)
{
var selected = GetRows().FirstOrDefault(x => ((TreeViewItemBase<SpriteCache>)x).customData.GetInstanceID() == selectedIds[0]) as TreeViewItemBase<SpriteCache>;
if (selected != null)
newSelected = selected.customData;
}
var skinningCache = newSelected.skinningCache;
using (skinningCache.UndoScope(TextContent.selectionChange))
{
skinningCache.events.selectedSpriteChanged.Invoke(newSelected);
}
}
public void SetSelection(SpriteCache sprite)
{
var rows = GetRows();
for (int i = 0; rows != null && i < rows.Count; ++i)
{
var r = (TreeViewItemBase<SpriteCache>)rows[i];
if (r.customData == sprite)
{
SetSelection(new[] { r.customData.GetInstanceID() }, TreeViewSelectionOptions.RevealAndFrame);
break;
}
}
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
{
var rows = GetRows() ?? new List<TreeViewItem>(200);
rows.Clear();
m_Sprites.RemoveAll(s => s == null);
foreach (var sprite in m_Sprites)
AddTreeViewItem(rows, sprite);
SetupDepthsFromParentsAndChildren(root);
return rows;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c86b96101a8b8f043a01b9c64b788b6b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98caf1503e1ef65468fc96b334fee770
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,438 @@
using System;
using UnityEngine.U2D.Common;
using UnityEditor.U2D.Layout;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.U2D.Animation
{
internal class VisibilityToolWindow : VisualElement, IVisibilityToolWindow
{
public class CustomUxmlFactory : UxmlFactory<VisibilityToolWindow, UxmlTraits> {}
VisualElement m_SelectorContainer;
VisualElement m_Container;
Slider m_BoneOpacitySlider;
Slider m_MeshOpacitySlider;
List<Button> m_Tabs;
int m_CurrentSelectedTab = 0;
public event Action<float> onBoneOpacitySliderChange = (f) => {};
public event Action<float> onMeshOpacitySliderChange = (f) => {};
public event Action onBoneOpacitySliderChangeBegin = () => {};
public event Action onBoneOpacitySliderChangeEnd = () => {};
public event Action onMeshOpacitySliderChangeBegin = () => {};
public event Action onMeshOpacitySliderChangeEnd = () => {};
public static VisibilityToolWindow CreateFromUXML()
{
var visualTree = ResourceLoader.Load<VisualTreeAsset>("SkinningModule/VisibilityToolWindow.uxml");
var ve = visualTree.CloneTree().Q("VisibilityToolWindow") as VisibilityToolWindow;
var resizer = ve.Q("Resizer");
resizer.AddManipulator(new VisibilityToolResizer());
ve.styleSheets.Add(ResourceLoader.Load<StyleSheet>("SkinningModule/VisibilityTool.uss"));
if (EditorGUIUtility.isProSkin)
ve.AddToClassList("Dark");
ve.BindElements();
return ve;
}
public void BindElements()
{
m_SelectorContainer = this.Q("VisibilityToolSelection");
m_Container = this.Q("VisibilityToolContainer");
m_BoneOpacitySlider = this.Q<Slider>("BoneOpacitySlider");
m_BoneOpacitySlider.RegisterValueChangedCallback(OnBoneOpacitySliderValueChangd);
m_MeshOpacitySlider = this.Q<Slider>("MeshOpacitySlider");
m_MeshOpacitySlider.RegisterValueChangedCallback(OnMeshOpacitySliderValueChangd);
RegisterCallback<MouseDownEvent>(OpacityChangeBegin, TrickleDown.TrickleDown);
RegisterCallback<MouseCaptureOutEvent>(OpacityChangeEnd, TrickleDown.TrickleDown);
// case 1200857 StopPropagation when bubbling up so that main IMGUI doesn't get the event
RegisterCallback<MouseDownEvent>(evt => evt.StopPropagation());
m_Tabs = new List<Button>();
m_SelectorContainer.Clear();
}
public void Initialize(LayoutOverlay layout)
{
layout.rightOverlay.Add(this);
Hide();
}
public void Show()
{
m_Container.Clear();
this.SetHiddenFromLayout(false);
}
public void Hide()
{
m_Container.Clear();
this.SetHiddenFromLayout(true);
}
bool IsOpacityTarget(IEventHandler target, VisualElement opacityTarget)
{
var ve = target as VisualElement;
while (ve != null && ve != this)
{
if (ve == opacityTarget)
return true;
ve = ve.parent;
}
return false;
}
void OpacityChangeBegin(MouseDownEvent evt)
{
if (IsOpacityTarget(evt.target, m_BoneOpacitySlider))
onBoneOpacitySliderChangeBegin();
else if (IsOpacityTarget(evt.target, m_MeshOpacitySlider))
onMeshOpacitySliderChangeBegin();
}
void OpacityChangeEnd(MouseCaptureOutEvent evt)
{
if (IsOpacityTarget(evt.target, m_BoneOpacitySlider))
onBoneOpacitySliderChangeEnd();
else if (IsOpacityTarget(evt.target, m_MeshOpacitySlider))
onMeshOpacitySliderChangeEnd();
}
void OnBoneOpacitySliderValueChangd(ChangeEvent<float> evt)
{
onBoneOpacitySliderChange(evt.newValue);
}
void OnMeshOpacitySliderValueChangd(ChangeEvent<float> evt)
{
onMeshOpacitySliderChange(evt.newValue);
}
public void SetBoneOpacitySliderValue(float value)
{
m_BoneOpacitySlider.value = value;
m_BoneOpacitySlider.MarkDirtyRepaint();
}
public void SetMeshOpacitySliderValue(float value)
{
m_MeshOpacitySlider.value = value;
m_MeshOpacitySlider.MarkDirtyRepaint();
}
public void AddToolTab(string name, Action onClick)
{
var tab = new Button()
{
text = name
};
tab.AddToClassList("visibilityToolTab");
if (EditorGUIUtility.isProSkin)
tab.AddToClassList("visibilityToolTabDark");
m_SelectorContainer.Add(tab);
m_Tabs.Add(tab);
tab.clickable.clicked += onClick;
}
public void SetActiveTab(int toolIndex)
{
if (m_Tabs.Count > toolIndex && toolIndex >= 0)
{
m_Tabs[m_CurrentSelectedTab].SetChecked(false);
m_Tabs[toolIndex].SetChecked(true);
m_CurrentSelectedTab = toolIndex;
}
}
public void SetContent(VisualElement content)
{
m_Container.Clear();
m_Container.Add(content);
}
public void SetToolAvailable(int toolIndex, bool available)
{
if (m_Tabs.Count > toolIndex && toolIndex >= 0)
{
m_Tabs[toolIndex].SetHiddenFromLayout(!available);
if (available == false && toolIndex == m_CurrentSelectedTab)
m_Container.Clear();
}
}
}
internal class VisibilityTool : BaseTool, IVisibilityToolModel
{
private VisibilityToolWindow m_ToolView;
private MeshPreviewBehaviour m_MeshPreviewBehaviour = new MeshPreviewBehaviour();
public SkeletonTool skeletonTool { set; private get; }
VisibilityToolController m_Controller;
internal override void OnCreate()
{
m_ToolView = VisibilityToolWindow.CreateFromUXML();
m_Controller = new VisibilityToolController(this, new IVisibilityTool[]
{
new BoneVisibilityTool(skinningCache),
new SpriteVisibilityTool(skinningCache)
},
() => skeletonTool,
() => previewBehaviour);
}
public override IMeshPreviewBehaviour previewBehaviour
{
get { return m_MeshPreviewBehaviour; }
}
public override void Initialize(LayoutOverlay layout)
{
m_ToolView.Initialize(layout);
}
protected override void OnGUI()
{
skeletonTool.skeletonStyle = SkeletonStyles.WeightMap;
skeletonTool.mode = SkeletonMode.EditPose;
skeletonTool.editBindPose = false;
skeletonTool.DoGUI();
}
protected override void OnActivate()
{
m_MeshPreviewBehaviour.showWeightMap = true;
m_Controller.Activate();
}
protected override void OnDeactivate()
{
m_Controller.Deactivate();
}
int IVisibilityToolModel.currentToolIndex
{
get
{
return skinningCache.visibililtyToolIndex;
}
set
{
skinningCache.visibililtyToolIndex = value;
}
}
float IVisibilityToolModel.boneOpacityValue
{
get
{
return VisibilityToolSettings.boneOpacity;
}
set
{
VisibilityToolSettings.boneOpacity = value;
}
}
float IVisibilityToolModel.meshOpacityValue
{
get
{
return VisibilityToolSettings.meshOpacity;
}
set
{
VisibilityToolSettings.meshOpacity = value;
}
}
UndoScope IVisibilityToolModel.UndoScope(string value)
{
return skinningCache.UndoScope(value);
}
void IVisibilityToolModel.BeginUndoOperation(string value)
{
skinningCache.BeginUndoOperation(value);
}
IVisibilityToolWindow IVisibilityToolModel.view { get { return m_ToolView;} }
SkinningCache IVisibilityToolModel.skinningCache { get { return skinningCache;} }
}
internal interface IVisibilityToolModel
{
int currentToolIndex { get; set; }
float meshOpacityValue { get; set; }
float boneOpacityValue { get; set; }
UndoScope UndoScope(string value);
void BeginUndoOperation(string value);
IVisibilityToolWindow view { get; }
SkinningCache skinningCache { get; }
}
internal interface IVisibilityToolWindow
{
void AddToolTab(string name, Action callback);
void SetToolAvailable(int i, bool available);
void SetBoneOpacitySliderValue(float value);
void SetMeshOpacitySliderValue(float value);
event Action<float> onBoneOpacitySliderChange;
event Action<float> onMeshOpacitySliderChange;
event Action onBoneOpacitySliderChangeBegin;
event Action onBoneOpacitySliderChangeEnd;
event Action onMeshOpacitySliderChangeBegin;
event Action onMeshOpacitySliderChangeEnd;
void Show();
void Hide();
void SetActiveTab(int index);
void SetContent(VisualElement content);
}
internal class VisibilityToolController
{
IVisibilityTool[] m_Tools;
IVisibilityToolModel m_Model;
Func<SkeletonTool> m_SkeletonTool;
Func<IMeshPreviewBehaviour> m_MeshPreviewBehaviour;
bool m_DeactivateBoneaTool = false;
private IVisibilityTool currentTool
{
get { return m_Model.currentToolIndex == -1 ? null : m_Tools[m_Model.currentToolIndex]; }
set { m_Model.currentToolIndex = value == null ? -1 : Array.FindIndex(m_Tools, x => x == value); }
}
private IVisibilityTool defaultTool
{
get { return Array.Find(m_Tools, t => t.isAvailable); }
}
public VisibilityToolController(IVisibilityToolModel model, IVisibilityTool[] tools, Func<SkeletonTool> skeletonTool = null, Func<IMeshPreviewBehaviour> meshPreviewBehaviour = null)
{
m_Model = model;
m_Tools = tools;
for (int i = 0; i < m_Tools.Length; ++i)
{
int index = i;
var tool = m_Tools[i];
tool.SetAvailabilityChangeCallback(() => OnToolAvailabilityChange(index));
tool.Setup();
model.view.AddToolTab(tool.name, () => ActivateToolWithUndo(tool));
model.view.SetToolAvailable(i, tool.isAvailable);
}
m_SkeletonTool = skeletonTool;
m_MeshPreviewBehaviour = meshPreviewBehaviour;
}
public void Activate()
{
m_Model.view.Show();
if (currentTool == null)
currentTool = defaultTool;
ActivateTool(currentTool);
m_Model.view.SetBoneOpacitySliderValue(m_Model.boneOpacityValue);
m_Model.view.SetMeshOpacitySliderValue(m_Model.meshOpacityValue);
m_Model.view.onBoneOpacitySliderChange -= OnBoneOpacityChange;
m_Model.view.onMeshOpacitySliderChange -= OnMeshOpacityChange;
m_Model.view.onBoneOpacitySliderChange += OnBoneOpacityChange;
m_Model.view.onMeshOpacitySliderChange += OnMeshOpacityChange;
m_Model.view.onBoneOpacitySliderChangeBegin -= OnBoneOpacityChangeBegin;
m_Model.view.onBoneOpacitySliderChangeBegin += OnBoneOpacityChangeBegin;
m_Model.view.onBoneOpacitySliderChangeEnd -= OnBoneOpacityChangeEnd;
m_Model.view.onBoneOpacitySliderChangeEnd += OnBoneOpacityChangeEnd;
m_Model.view.onMeshOpacitySliderChangeBegin -= OnMeshOpacityChangeBegin;
m_Model.view.onMeshOpacitySliderChangeBegin += OnMeshOpacityChangeBegin;
m_Model.view.onMeshOpacitySliderChangeEnd -= OnMeshOpacityChangeEnd;
m_Model.view.onMeshOpacitySliderChangeEnd += OnMeshOpacityChangeEnd;
}
public void Deactivate()
{
m_Model.view.Hide();
if (currentTool != null)
currentTool.Deactivate();
m_Model.view.onBoneOpacitySliderChange -= OnBoneOpacityChange;
m_Model.view.onMeshOpacitySliderChange -= OnMeshOpacityChange;
m_Model.view.onBoneOpacitySliderChangeBegin -= OnBoneOpacityChangeBegin;
m_Model.view.onBoneOpacitySliderChangeEnd -= OnBoneOpacityChangeEnd;
m_Model.view.onMeshOpacitySliderChangeBegin -= OnMeshOpacityChangeBegin;
m_Model.view.onMeshOpacitySliderChangeEnd -= OnMeshOpacityChangeEnd;
}
void OnBoneOpacityChangeBegin()
{
if (m_SkeletonTool != null && m_SkeletonTool() != null && !m_SkeletonTool().isActive)
{
m_SkeletonTool().Activate();
m_DeactivateBoneaTool = true;
}
}
void OnBoneOpacityChangeEnd()
{
if (m_SkeletonTool != null && m_SkeletonTool() != null && m_SkeletonTool().isActive && m_DeactivateBoneaTool)
m_SkeletonTool().Deactivate();
}
void OnMeshOpacityChangeBegin()
{
m_Model.skinningCache.events.meshPreviewBehaviourChange.Invoke(m_MeshPreviewBehaviour());
}
void OnMeshOpacityChangeEnd()
{
m_Model.skinningCache.events.meshPreviewBehaviourChange.Invoke(null);
}
private void OnBoneOpacityChange(float value)
{
m_Model.boneOpacityValue = value;
}
private void OnMeshOpacityChange(float value)
{
m_Model.meshOpacityValue = value;
}
private void OnToolAvailabilityChange(int toolIndex)
{
var toolChanged = m_Tools[toolIndex];
m_Model.view.SetToolAvailable(toolIndex, toolChanged.isAvailable);
if (toolChanged == currentTool && toolChanged.isAvailable == false)
ActivateTool(defaultTool);
}
private void ActivateToolWithUndo(IVisibilityTool tool)
{
if (currentTool != tool && tool.isAvailable)
{
m_Model.BeginUndoOperation(TextContent.visibilityTab);
ActivateTool(tool);
}
}
private void ActivateTool(IVisibilityTool tool)
{
if (tool.isAvailable == false)
return;
if (currentTool != null)
currentTool.Deactivate();
currentTool = tool;
currentTool.Activate();
m_Model.view.SetActiveTab(m_Model.currentToolIndex);
m_Model.view.SetContent(currentTool.view);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad7233a4a9bae914696f0c4fe3c9c8c1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,124 @@
using System;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.U2D.Animation
{
internal interface IVisibilityTool
{
VisualElement view { get; }
string name { get; }
void Activate();
void Deactivate();
bool isAvailable { get; }
void SetAvailabilityChangeCallback(Action callback);
void Setup();
void Dispose();
}
internal class VisibilityToolViewBase : VisualElement
{
IMGUIContainer m_Container;
SearchField m_SearchField;
protected TreeView m_TreeView;
protected TreeViewState m_TreeViewState = new TreeViewState();
public Action<float> SetOpacityValue = null;
public Func<float> GetOpacityValue = null;
protected static class Styles
{
public static readonly GUIStyle preLabel = "preLabel";
public static readonly GUIStyle preSlider = "preSlider";
public static readonly GUIStyle preSliderThumb = "preSliderThumb";
}
public VisibilityToolViewBase()
{
m_Container = new IMGUIContainer(OnGUI);
this.Add(m_Container);
m_TreeViewState.searchString = "";
}
protected void SetupSearchField()
{
m_SearchField = new SearchField();
m_SearchField.downOrUpArrowKeyPressed += m_TreeView.SetFocusAndEnsureSelectedItem;
}
void DoSearchField()
{
m_SearchField.downOrUpArrowKeyPressed += m_TreeView.SetFocusAndEnsureSelectedItem;
GUILayout.BeginHorizontal(EditorStyles.toolbar);
m_TreeView.searchString = m_SearchField.OnToolbarGUI(m_TreeView.searchString);
GUILayout.EndHorizontal();
}
void DoOpacitySlider()
{
if (GetOpacityValue != null && SetOpacityValue != null)
{
GUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUI.BeginChangeCheck();
var opacity = GUILayout.HorizontalSlider(GetOpacityValue(), 0, 1, Styles.preSlider, Styles.preSliderThumb);
if (EditorGUI.EndChangeCheck())
SetOpacityValue(opacity);
GUILayout.EndHorizontal();
}
}
void OnGUI()
{
GUILayout.BeginVertical();
DoSearchField();
GUILayout.EndVertical();
Rect rect = GUILayoutUtility.GetRect(0, 100000, 0, 100000);
m_TreeView.OnGUI(rect);
DoOpacitySlider();
}
}
internal class TreeViewItemBase<T> : TreeViewItem
{
public T customData;
public TreeViewItemBase(int id, int depth, string name, T data) : base(id, depth, name)
{
customData = data;
}
}
internal class VisibilityTreeViewBase : TreeView
{
static internal class VisibilityIconStyle
{
public static readonly GUIContent visibilityOnIcon = new GUIContent(IconUtility.LoadIconResource("Visibility_Tool", IconUtility.k_LightIconResourcePath, IconUtility.k_DarkIconResourcePath), L10n.Tr("On"));
public static readonly GUIContent visibilityOffIcon = new GUIContent(IconUtility.LoadIconResource("Visibility_Hidded", IconUtility.k_LightIconResourcePath, IconUtility.k_DarkIconResourcePath), L10n.Tr("Off"));
}
public VisibilityTreeViewBase(TreeViewState treeViewState, MultiColumnHeader multiColumn)
: base(treeViewState, multiColumn)
{
Init();
}
public VisibilityTreeViewBase(TreeViewState treeViewState)
: base(treeViewState)
{
Init();
}
void Init()
{
this.showAlternatingRowBackgrounds = true;
this.useScrollView = true;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem { id = 0, depth = -1 };
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 80b572e0f086ba540b44ec45a404263a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,35 @@
using System;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace UnityEditor.U2D.Animation
{
internal class VisibilityToolColumnHeader : MultiColumnHeader
{
public Action<bool> SetAllVisibility = (b) => {};
public Func<bool> GetAllVisibility = () => true;
public VisibilityToolColumnHeader(MultiColumnHeaderState state)
: base(state)
{
visibilityColumn = -1;
}
public int visibilityColumn { private get; set; }
protected override void ColumnHeaderGUI(MultiColumnHeaderState.Column column, Rect headerRect, int columnIndex)
{
if (columnIndex == visibilityColumn)
{
GUIStyle style = DefaultStyles.columnHeaderCenterAligned;
EditorGUI.BeginChangeCheck();
var visibility = GetAllVisibility();
visibility = GUI.Toggle(headerRect, visibility, visibility ? VisibilityTreeViewBase.VisibilityIconStyle.visibilityOnIcon : VisibilityTreeViewBase.VisibilityIconStyle.visibilityOffIcon, style);
if (EditorGUI.EndChangeCheck())
SetAllVisibility(visibility);
}
else
base.ColumnHeaderGUI(column, headerRect, columnIndex);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 11be01bfe5fde8f419a0ec4a38e1026e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,87 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.U2D.Layout
{
internal class VisibilityToolResizer : MouseManipulator
{
private Vector2 m_Start;
private VisualElement m_Root;
protected bool m_Active;
private Rect m_StartPos;
public VisibilityToolResizer()
{
activators.Add(new ManipulatorActivationFilter {button = MouseButton.LeftMouse});
m_Active = false;
}
protected override void RegisterCallbacksOnTarget()
{
target.RegisterCallback<MouseDownEvent>(OnMouseDown);
target.RegisterCallback<MouseMoveEvent>(OnMouseMove);
target.RegisterCallback<MouseUpEvent>(OnMouseUp);
}
protected override void UnregisterCallbacksFromTarget()
{
target.UnregisterCallback<MouseDownEvent>(OnMouseDown);
target.UnregisterCallback<MouseMoveEvent>(OnMouseMove);
target.UnregisterCallback<MouseUpEvent>(OnMouseUp);
}
protected void OnMouseDown(MouseDownEvent e)
{
if (m_Active)
{
e.StopImmediatePropagation();
return;
}
if (CanStartManipulation(e))
{
m_Root = target;
while (m_Root.parent != null)
m_Root = m_Root.parent;
m_Start = target.ChangeCoordinatesTo(m_Root, e.localMousePosition);
m_StartPos = target.parent.layout;
m_Active = true;
target.CaptureMouse();
e.StopPropagation();
}
}
protected void OnMouseMove(MouseMoveEvent e)
{
if (m_Active)
{
var ce = target.parent;
Vector2 diff = target.ChangeCoordinatesTo(m_Root, e.localMousePosition) - m_Start;
var newSize = new Vector2(m_StartPos.width - diff.x, m_StartPos.height - diff.y);
float minWidth = ce.resolvedStyle.minWidth == StyleKeyword.Auto ? 0 : ce.resolvedStyle.minWidth.value;
float minHeight = ce.resolvedStyle.minHeight == StyleKeyword.Auto ? 0 : ce.resolvedStyle.minHeight.value;
float maxWidth = ce.resolvedStyle.maxWidth == StyleKeyword.None ? float.MaxValue : ce.resolvedStyle.maxWidth.value;
float maxHeight = ce.resolvedStyle.maxHeight == StyleKeyword.None ? float.MaxValue : ce.resolvedStyle.maxHeight.value;
newSize.x = (newSize.x < minWidth) ? minWidth : ((newSize.x > maxWidth) ? maxWidth : newSize.x);
newSize.y = (newSize.y < minHeight) ? minHeight : ((newSize.y > maxHeight) ? maxHeight : newSize.y);
ce.style.width = newSize.x;
e.StopPropagation();
}
}
protected void OnMouseUp(MouseUpEvent e)
{
if (m_Active)
{
if (CanStopManipulation(e))
{
m_Active = false;
target.ReleaseMouse();
e.StopPropagation();
}
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e28e411d271b90e45894708257ca80fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: