A game about forced loneliness, made by TACStudios
at master 293 lines 10 kB view raw
1using System; 2using System.Collections.Generic; 3using UnityEditor.U2D.Common; 4using UnityEngine; 5using UnityEngine.UIElements; 6 7namespace UnityEditor.U2D.Animation 8{ 9#if ENABLE_UXML_SERIALIZED_DATA 10 [UxmlElement] 11#endif 12 internal partial class WeightPainterPanel : VisualElement 13 { 14#if ENABLE_UXML_TRAITS 15 public class WeightPainterPanelFactory : UxmlFactory<WeightPainterPanel, WeightPainterPanelUxmlTraits> {} 16 public class WeightPainterPanelUxmlTraits : UxmlTraits {} 17#endif 18 public static readonly string kNone = "None"; 19 20 private WeightPainterMode m_PaintMode; 21 private EnumField m_ModeField; 22 private Toggle m_NormalizeToggle; 23 private IntegerField m_HardnessField; 24 private IntegerField m_StepField; 25 private IntegerField m_SizeField; 26 private FloatField m_AmountField; 27 private Slider m_AmountSlider; 28 private VisualElement m_BonePopupContainer; 29 private PopupField<string> m_BonePopup; 30 private bool m_SliderActive = false; 31 private WeightInspectorIMGUIPanel m_WeightInspectorPanel; 32 private UnityEngine.UIElements.PopupWindow m_PopupWindow; 33 34 public event Action<int> bonePopupChanged = (s) => {}; 35 public event Action sliderStarted = () => {}; 36 public event Action<float> sliderChanged = (s) => {}; 37 public event Action sliderEnded = () => {}; 38 public event Action weightsChanged = () => {}; 39 40 public WeightPainterMode paintMode 41 { 42 get { return m_PaintMode; } 43 set 44 { 45 if (value == m_PaintMode) 46 return; 47 48 m_PaintMode = value; 49 if (m_PaintMode == WeightPainterMode.Brush) 50 { 51 RemoveFromClassList("SliderMode"); 52 AddToClassList("BrushMode"); 53 } 54 else 55 { 56 RemoveFromClassList("BrushMode"); 57 AddToClassList("SliderMode"); 58 } 59 } 60 } 61 62 public string title 63 { 64 set { m_PopupWindow.text = value; } 65 } 66 67 public WeightEditorMode mode 68 { 69 get { return (WeightEditorMode)m_ModeField.value; } 70 set { m_ModeField.value = value; } 71 } 72 73 public int boneIndex 74 { 75 get { return m_BonePopup.index - 1; } 76 } 77 78 public int size 79 { 80 get { return m_SizeField.value; } 81 set { m_SizeField.value = value; } 82 } 83 84 public int hardness 85 { 86 get { return m_HardnessField.value; } 87 set { m_HardnessField.value = value; } 88 } 89 90 public int step 91 { 92 get { return m_StepField.value; } 93 set { m_StepField.value = value; } 94 } 95 96 public bool normalize 97 { 98 get { return m_NormalizeToggle.value; } 99 set { m_NormalizeToggle.value = value; } 100 } 101 102 public float amount 103 { 104 get { return m_AmountField.value; } 105 set { m_AmountField.value = value; } 106 } 107 108 public WeightPainterPanel() 109 { 110 styleSheets.Add(ResourceLoader.Load<StyleSheet>("SkinningModule/WeightPainterPanelStyle.uss")); 111 if (EditorGUIUtility.isProSkin) 112 AddToClassList("Dark"); 113 114 paintMode = WeightPainterMode.Brush; 115 AddToClassList("BrushMode"); 116 117 RegisterCallback<MouseDownEvent>((e) => { e.StopPropagation(); }); 118 RegisterCallback<MouseUpEvent>((e) => { e.StopPropagation(); }); 119 } 120 121 public void BindElements() 122 { 123 m_ModeField = this.Q<EnumField>("ModeField"); 124 m_BonePopupContainer = this.Q<VisualElement>("BoneEnumPopup"); 125 m_NormalizeToggle = this.Q<Toggle>("NormalizeToggle"); 126 m_SizeField = this.Q<IntegerField>("SizeField"); 127 m_HardnessField = this.Q<IntegerField>("HardnessField"); 128 m_StepField = this.Q<IntegerField>("StepField"); 129 m_AmountSlider = this.Q<Slider>("AmountSlider"); 130 m_AmountField = this.Q<FloatField>("AmountField"); 131 m_AmountField.isDelayed = true; 132 m_WeightInspectorPanel = this.Q<WeightInspectorIMGUIPanel>("WeightsInspector"); 133 m_PopupWindow = this.Q<UnityEngine.UIElements.PopupWindow>(); 134 135 LinkSliderToIntegerField(this.Q<Slider>("HardnessSlider"), m_HardnessField); 136 LinkSliderToIntegerField(this.Q<Slider>("StepSlider"), m_StepField); 137 138 m_ModeField.RegisterValueChangedCallback((evt) => 139 { 140 SetupMode(); 141 }); 142 143 m_AmountSlider.RegisterValueChangedCallback((evt) => 144 { 145 if (!evt.Equals(m_AmountField.value)) 146 m_AmountField.value = (float)Math.Round((double)evt.newValue, 2); 147 if (m_SliderActive) 148 sliderChanged?.Invoke(m_AmountField.value); 149 }); 150 m_AmountSlider.RegisterCallback<MouseCaptureEvent>(evt => 151 { 152 m_SliderActive = true; 153 sliderStarted?.Invoke(); 154 }, TrickleDown.TrickleDown); 155 156 m_AmountSlider.RegisterCallback<MouseCaptureOutEvent>(evt => 157 { 158 m_SliderActive = false; 159 sliderEnded?.Invoke(); 160 m_AmountSlider.value = 0; 161 }, TrickleDown.TrickleDown); 162 163 m_AmountField.RegisterValueChangedCallback((evt) => 164 { 165 var newValue = Mathf.Clamp(evt.newValue, m_AmountSlider.lowValue, m_AmountSlider.highValue); 166 167 if (focusController.focusedElement == m_AmountField && !newValue.Equals(m_AmountSlider.value)) 168 { 169 sliderStarted(); 170 sliderChanged(newValue); 171 sliderEnded(); 172 Focus(); 173 m_AmountField.value = 0f; 174 m_AmountSlider.value = 0f; 175 } 176 }); 177 178 m_WeightInspectorPanel.weightsChanged += () => weightsChanged(); 179 } 180 181 public void SetActive(bool active) 182 { 183 this.Q("Amount").SetEnabled(active); 184 } 185 186 private void SetupMode() 187 { 188 var boneElement = this.Q<VisualElement>("Bone"); 189 boneElement.SetHiddenFromLayout(mode == WeightEditorMode.Smooth); 190 SetupAmountSlider(); 191 } 192 193 private void SetupAmountSlider() 194 { 195 if (paintMode == WeightPainterMode.Slider) 196 { 197 if (mode == WeightEditorMode.Smooth) 198 { 199 m_AmountSlider.lowValue = 0.0f; 200 m_AmountSlider.highValue = 8.0f; 201 } 202 else 203 { 204 m_AmountSlider.lowValue = -1.0f; 205 m_AmountSlider.highValue = 1.0f; 206 } 207 } 208 } 209 210 private void LinkSliderToIntegerField(Slider slider, IntegerField field) 211 { 212 slider.RegisterValueChangedCallback((evt) => 213 { 214 if (!evt.newValue.Equals(field.value)) 215 field.value = Mathf.RoundToInt(evt.newValue); 216 }); 217 field.RegisterValueChangedCallback((evt) => 218 { 219 if (!evt.newValue.Equals((int)slider.value)) 220 slider.value = evt.newValue; 221 }); 222 } 223 224 public void UpdateWeightInspector(BaseSpriteMeshData spriteMeshData, string[] boneNames, ISelection<int> selection, ICacheUndo cacheUndo) 225 { 226 m_WeightInspectorPanel.weightInspector.spriteMeshData = spriteMeshData; 227 m_WeightInspectorPanel.weightInspector.boneNames = ModuleUtility.ToGUIContentArray(boneNames); 228 m_WeightInspectorPanel.weightInspector.selection = selection; 229 m_WeightInspectorPanel.weightInspector.cacheUndo = cacheUndo; 230 } 231 232 public void UpdatePanel(string[] boneNames) 233 { 234 SetupMode(); 235 UpdateBonePopup(boneNames); 236 } 237 238 private void UpdateBonePopup(string[] names) 239 { 240 VisualElement boneElement = null; 241 if (m_ModeField != null && mode == WeightEditorMode.Smooth) 242 { 243 boneElement = this.Q<VisualElement>("Bone"); 244 boneElement.SetHiddenFromLayout(false); 245 } 246 247 if (m_BonePopup != null) 248 { 249 m_BonePopupContainer.Remove(m_BonePopup); 250 } 251 252 m_BonePopup = new PopupField<string>(new List<string>(names), 0); 253 m_BonePopup.name = "BonePopupField"; 254 m_BonePopup.label = TextContent.bone; 255 m_BonePopup.tooltip = TextContent.boneToolTip; 256 m_BonePopup.RegisterValueChangedCallback((evt) => 257 { 258 bonePopupChanged(boneIndex); 259 }); 260 m_BonePopupContainer.Add(m_BonePopup); 261 262 if (boneElement != null) 263 { 264 boneElement.SetHiddenFromLayout(true); 265 } 266 } 267 268 internal void SetBoneSelectionByName(string boneName) 269 { 270 if (m_BonePopup != null) 271 m_BonePopup.value = boneName; 272 } 273 274 public static WeightPainterPanel GenerateFromUXML() 275 { 276 var visualTree = ResourceLoader.Load<VisualTreeAsset>("SkinningModule/WeightPainterPanel.uxml"); 277 var clone = visualTree.CloneTree().Q<WeightPainterPanel>("WeightPainterPanel"); 278 clone.LocalizeTextInChildren(); 279 280 // EnumField can only get type of Enum from the current running assembly when defined through UXML 281 // Manually create the EnumField here 282 var mode = clone.Q<VisualElement>("Mode"); 283 var modeField = new EnumField(WeightEditorMode.AddAndSubtract); 284 modeField.name = "ModeField"; 285 modeField.label = TextContent.mode; 286 modeField.tooltip = TextContent.modeTooltip; 287 mode.Add(modeField); 288 289 clone.BindElements(); 290 return clone; 291 } 292 } 293}