init
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using Cursor = UnityEngine.Cursor;
|
||||
|
||||
namespace RPGCoreCommon.DropTable.Editor
|
||||
{
|
||||
internal class DropTableGroupRowElement : VisualElement
|
||||
{
|
||||
// Property data
|
||||
private SerializedProperty _property;
|
||||
private SerializedProperty _propertyInlineGroup;
|
||||
private DropTableGroupRow value => (DropTableGroupRow)_property.boxedValue;
|
||||
|
||||
// Elements
|
||||
private readonly VisualElement _percentBackground;
|
||||
private readonly Label _percentLabel;
|
||||
private readonly VisualElement _rightElement;
|
||||
private readonly FloatField _chanceField;
|
||||
private readonly IntegerField _countField;
|
||||
private readonly ObjectField _itemField;
|
||||
private readonly ObjectField _groupReferenceField;
|
||||
private readonly DropTableGroupElement _groupInline;
|
||||
private readonly Label _newInlineLabel;
|
||||
private readonly VisualElement _dropHere;
|
||||
|
||||
internal DropTableGroupRowElement()
|
||||
{
|
||||
DropTableDrawer.rowVisualTreeAsset.CloneTree(this);
|
||||
|
||||
this.AddManipulator(new ContextualMenuManipulator(null));
|
||||
RegisterCallback<ContextualMenuPopulateEvent>(ev =>
|
||||
{
|
||||
ev.StopImmediatePropagation();
|
||||
|
||||
ev.menu.InsertAction(0, "Reset row", _ =>
|
||||
{
|
||||
SetEditingMode(EditTypeEnum.None);
|
||||
});
|
||||
ev.menu.InsertAction(1, "Remove row", _ =>
|
||||
{
|
||||
var arrayPath = string.Join(".", _property.propertyPath.Split(".").SkipLast(2));
|
||||
var arrayProperty = _property.serializedObject.FindProperty(arrayPath);
|
||||
var i = int.Parse(_property.propertyPath[_property.propertyPath.LastIndexOf('[')..].Trim('[', ']'));
|
||||
arrayProperty.DeleteArrayElementAtIndex(i);
|
||||
_property.serializedObject.ApplyModifiedProperties();
|
||||
});
|
||||
ev.menu.InsertSeparator(null, 2);
|
||||
});
|
||||
|
||||
// PERCENTAGE
|
||||
_percentBackground = this.Q("dt-percent-background");
|
||||
_percentLabel = this.Q<Label>("dt-percent");
|
||||
|
||||
// RIGHT SIDE
|
||||
_rightElement = this.Q("dt-right");
|
||||
|
||||
// CHANCE
|
||||
_chanceField = this.Q<FloatField>("dt-chance");
|
||||
_chanceField.RegisterValueChangedCallback(_ =>
|
||||
{
|
||||
_chanceField.SetValueWithoutNotify(Mathf.Clamp(_chanceField.value, 0, 100));
|
||||
RefreshGroup();
|
||||
});
|
||||
|
||||
// COUNT
|
||||
_countField = this.Q<IntegerField>("dt-count");
|
||||
_countField.RegisterValueChangedCallback(_ => _countField.SetValueWithoutNotify(Mathf.Max(0, _countField.value)));
|
||||
|
||||
// CREATE INLINE
|
||||
_newInlineLabel = this.Q<Label>("dt-new-inline");
|
||||
_newInlineLabel.RegisterCallback<ClickEvent>(_ => SetEditingMode(EditTypeEnum.InlineGroup));
|
||||
|
||||
// DROP AREA
|
||||
_dropHere = this.Q("dt-drop-here");
|
||||
RegisterCallback<DragLeaveEvent>(_ => ShowDropHere());
|
||||
RegisterCallback<DragExitedEvent>(_ => ShowDropHere());
|
||||
RegisterCallback<DragUpdatedEvent>(ev =>
|
||||
{
|
||||
if ((ev.target as VisualElement).GetFirstAncestorOfType<DropTableGroupRowElement>() != this)
|
||||
{
|
||||
ShowDropHere(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.subGroupInline is not null)
|
||||
{
|
||||
ShowDropHere(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ShowDropHere(true);
|
||||
});
|
||||
RegisterCallback<DragPerformEvent>(ev =>
|
||||
{
|
||||
ev.StopImmediatePropagation();
|
||||
|
||||
if (DragAndDrop.objectReferences.Length > 1)
|
||||
Debug.LogWarning("Trying to drag more than one <b>Object</b> to row, using only first one.");
|
||||
|
||||
SetEditingMode(EditTypeEnum.None);
|
||||
|
||||
var obj = DragAndDrop.objectReferences[0];
|
||||
if (obj is DropTableSO dropTableSO)
|
||||
{
|
||||
_groupReferenceField.value = dropTableSO;
|
||||
SetEditingMode(EditTypeEnum.ReferenceGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
_itemField.value = obj;
|
||||
SetEditingMode(EditTypeEnum.Item);
|
||||
}
|
||||
|
||||
ShowDropHere();
|
||||
});
|
||||
|
||||
// ITEM
|
||||
_itemField = this.Q<ObjectField>("dt-item");
|
||||
|
||||
// SUBGROUP REF
|
||||
_groupReferenceField = this.Q<ObjectField>("dt-group-reference");
|
||||
_groupReferenceField.objectType = typeof(DropTableSO);
|
||||
|
||||
// SUBGROUP INLINE
|
||||
_groupInline = new DropTableGroupElement { name = "dt-group-inline" };
|
||||
this.Q("dt-body").Add(_groupInline);
|
||||
|
||||
SetEnabled(false);
|
||||
}
|
||||
|
||||
private void ShowDropHere()
|
||||
{
|
||||
ShowDropHere(!value.item && !value.subGroupRef && value.subGroupInline is null);
|
||||
}
|
||||
|
||||
private void ShowDropHere(bool show)
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
_dropHere.style.display = DisplayStyle.Flex;
|
||||
_dropHere.pickingMode = PickingMode.Position;
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||
|
||||
ShowCreateNewInline(!value.item && !value.subGroupRef && value.subGroupInline is null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dropHere.style.display = DisplayStyle.None;
|
||||
_dropHere.pickingMode = PickingMode.Ignore;
|
||||
ShowCreateNewInline(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowCreateNewInline(bool show)
|
||||
{
|
||||
_newInlineLabel.style.display = show ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
|
||||
internal void BindProperty(SerializedProperty property)
|
||||
{
|
||||
SetEnabled(true);
|
||||
|
||||
_property = property;
|
||||
_propertyInlineGroup = property.FindPropertyRelative(nameof(DropTableGroupRow.subGroupInline));
|
||||
var value = _property.boxedValue as DropTableGroupRow;
|
||||
|
||||
_chanceField.BindProperty(_property.FindPropertyRelative(nameof(DropTableGroupRow.chance)));
|
||||
_countField.BindProperty(_property.FindPropertyRelative(nameof(DropTableGroupRow.count)));
|
||||
_itemField.BindProperty(_property.FindPropertyRelative(nameof(DropTableGroupRow.item)));
|
||||
_groupReferenceField.BindProperty(_property.FindPropertyRelative(nameof(DropTableGroupRow.subGroupRef)));
|
||||
|
||||
// Default editing mode by currently set content
|
||||
if (value.item) SetEditingMode(EditTypeEnum.Item);
|
||||
else if (value.subGroupRef) SetEditingMode(EditTypeEnum.ReferenceGroup);
|
||||
else if (value.subGroupInline != null) SetEditingMode(EditTypeEnum.InlineGroup);
|
||||
else SetEditingMode(EditTypeEnum.None);
|
||||
}
|
||||
|
||||
private void SetEditingMode(EditTypeEnum @enum)
|
||||
{
|
||||
// Hide all
|
||||
_itemField.style.display = DisplayStyle.None;
|
||||
_groupReferenceField.style.display = DisplayStyle.None;
|
||||
_groupInline.style.display = DisplayStyle.None;
|
||||
|
||||
switch (@enum)
|
||||
{
|
||||
// 1. Starting point when row is newly created with no values
|
||||
// 2. When row is resetting - clean values
|
||||
case EditTypeEnum.None:
|
||||
_itemField.value = null;
|
||||
_groupReferenceField.value = null;
|
||||
_propertyInlineGroup.managedReferenceValue = null;
|
||||
_rightElement.EnableInClassList("single-line", false);
|
||||
ShowDropHere(true);
|
||||
break;
|
||||
// Editing selected - item
|
||||
case EditTypeEnum.Item:
|
||||
_itemField.style.display = DisplayStyle.Flex;
|
||||
_rightElement.EnableInClassList("single-line", true);
|
||||
ShowDropHere(false);
|
||||
break;
|
||||
// Editing selected - recursion by reference (ScriptableObject)
|
||||
case EditTypeEnum.ReferenceGroup:
|
||||
_groupReferenceField.style.display = DisplayStyle.Flex;
|
||||
_rightElement.EnableInClassList("single-line", true);
|
||||
ShowDropHere(false);
|
||||
break;
|
||||
// Editing selected - recursion by inline definition
|
||||
case EditTypeEnum.InlineGroup:
|
||||
_groupInline.style.display = DisplayStyle.Flex;
|
||||
_propertyInlineGroup.managedReferenceValue ??= new DropTableGroup();
|
||||
_property.serializedObject.ApplyModifiedProperties();
|
||||
_groupInline.BindProperty(_propertyInlineGroup);
|
||||
_rightElement.EnableInClassList("single-line", false);
|
||||
ShowDropHere(false);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
internal void RefreshGroup()
|
||||
{
|
||||
GetFirstAncestorOfType<DropTableGroupElement>().Refresh();
|
||||
}
|
||||
|
||||
internal void Refresh(ChanceTypeEnum chanceType, float weightSum)
|
||||
{
|
||||
switch (chanceType)
|
||||
{
|
||||
case ChanceTypeEnum.All:
|
||||
_chanceField.style.display = DisplayStyle.None;
|
||||
_percentBackground.style.display = DisplayStyle.None;
|
||||
break;
|
||||
case ChanceTypeEnum.ByWeight:
|
||||
_chanceField.style.display = DisplayStyle.Flex;
|
||||
_chanceField.label = "Weight:";
|
||||
_percentBackground.style.display = DisplayStyle.Flex;
|
||||
SetPercent(_chanceField.value/weightSum*100);
|
||||
break;
|
||||
case ChanceTypeEnum.ByPercent:
|
||||
_chanceField.style.display = DisplayStyle.Flex;
|
||||
_chanceField.label = "Percent:";
|
||||
_percentBackground.style.display = DisplayStyle.Flex;
|
||||
SetPercent(_chanceField.value);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(chanceType), chanceType, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPercent(float percent)
|
||||
{
|
||||
_percentBackground.style.backgroundColor = Color.Lerp(Color.red, Color.green, percent / 100);
|
||||
_percentLabel.text = $"{percent:F}%";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user