mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Initial commit
This commit is contained in:
commit
3c7cc0c973
8391 changed files with 704313 additions and 0 deletions
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a660ba45386a23843a274d00b171e0fc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 40cebb2c3989f5844a7cbdc20bb68bdf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dc4f326c25da1c048a6365f4f5c7198e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a0e8a5f39ab443849ac34497669e976f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fc0f7df10f714e0458bbe6f652412bda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c86b96101a8b8f043a01b9c64b788b6b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 98caf1503e1ef65468fc96b334fee770
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ad7233a4a9bae914696f0c4fe3c9c8c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 80b572e0f086ba540b44ec45a404263a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 11be01bfe5fde8f419a0ec4a38e1026e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e28e411d271b90e45894708257ca80fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue