Add undo for #1247

This commit is contained in:
Wojtek Figat
2023-07-18 11:46:15 +02:00
parent 8f8c0e4b81
commit 60c0995bc3
2 changed files with 79 additions and 39 deletions

View File

@@ -38,6 +38,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// </summary>
public AssetPicker Picker;
private bool _isRefreshing;
private ScriptType _valueType;
/// <inheritdoc />
@@ -89,6 +90,8 @@ namespace FlaxEditor.CustomEditors.Editors
private void OnSelectedItemChanged()
{
if (_isRefreshing)
return;
if (typeof(AssetItem).IsAssignableFrom(_valueType.Type))
SetValue(Picker.SelectedItem);
else if (_valueType.Type == typeof(Guid))
@@ -108,6 +111,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (!HasDifferentValues)
{
_isRefreshing = true;
if (Values[0] is AssetItem assetItem)
Picker.SelectedItem = assetItem;
else if (Values[0] is Guid guid)
@@ -118,6 +122,7 @@ namespace FlaxEditor.CustomEditors.Editors
Picker.SelectedPath = path;
else
Picker.SelectedAsset = Values[0] as Asset;
_isRefreshing = false;
}
}
}

View File

@@ -15,7 +15,11 @@ namespace FlaxEditor.CustomEditors.Editors
{
private GroupElement _group;
private bool _updateName;
private int _entryIndex;
private bool _isRefreshing;
private MaterialBase _material;
private ModelInstanceActor _modelInstance;
private AssetRefEditor _materialEditor;
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
@@ -32,58 +36,75 @@ namespace FlaxEditor.CustomEditors.Editors
materialLabel.TooltipText = "The mesh surface material used for the rendering.";
if (ParentEditor.ParentEditor?.Values[0] is ModelInstanceActor modelInstance)
{
// Ensure that entry with default material set is set back to null
var defaultValue = GPUDevice.Instance.DefaultMaterial;
_entryIndex = entryIndex;
_modelInstance = modelInstance;
var slots = modelInstance.MaterialSlots;
if (entry.Material == slots[entryIndex].Material)
{
var slots = modelInstance.MaterialSlots;
if (entry.Material == slots[entryIndex].Material)
{
modelInstance.SetMaterial(entryIndex, null);
}
_material = modelInstance.GetMaterial(entryIndex);
if (slots[entryIndex].Material)
{
defaultValue = slots[entryIndex].Material;
}
// Ensure that entry with default material set is set back to null
modelInstance.SetMaterial(entryIndex, null);
}
_material = modelInstance.GetMaterial(entryIndex);
var defaultValue = GPUDevice.Instance.DefaultMaterial;
if (slots[entryIndex].Material)
{
// Use default value set on asset (eg. Model Asset)
defaultValue = slots[entryIndex].Material;
}
var matContainer = new CustomValueContainer(new ScriptType(typeof(MaterialBase)), _material, (instance, index) => _material, (instance, index, value) => _material = value as MaterialBase);
var materialEditor = (AssetRefEditor)_group.Property(materialLabel, matContainer);
// Create material picker
var materialValue = new CustomValueContainer(new ScriptType(typeof(MaterialBase)), _material, (instance, index) => _material, (instance, index, value) => _material = value as MaterialBase);
var materialEditor = (AssetRefEditor)_group.Property(materialLabel, materialValue);
materialEditor.Values.SetDefaultValue(defaultValue);
materialEditor.RefreshDefaultValue();
materialEditor.Picker.SelectedItemChanged += () =>
{
var slots = modelInstance.MaterialSlots;
var material = materialEditor.Picker.SelectedAsset as MaterialBase;
var defaultMaterial = GPUDevice.Instance.DefaultMaterial;
if (!material)
{
modelInstance.SetMaterial(entryIndex, defaultMaterial);
materialEditor.Picker.SelectedAsset = defaultMaterial;
}
else if (material == slots[entryIndex].Material)
{
modelInstance.SetMaterial(entryIndex, null);
}
else if (material == defaultMaterial && !slots[entryIndex].Material)
{
modelInstance.SetMaterial(entryIndex, null);
}
else
{
modelInstance.SetMaterial(entryIndex, material);
}
};
materialEditor.Picker.SelectedItemChanged += OnSelectedMaterialChanged;
_materialEditor = materialEditor;
}
base.Initialize(group);
}
private void OnSelectedMaterialChanged()
{
if (_isRefreshing)
return;
_isRefreshing = true;
var slots = _modelInstance.MaterialSlots;
var material = _materialEditor.Picker.SelectedAsset as MaterialBase;
var defaultMaterial = GPUDevice.Instance.DefaultMaterial;
var value = (ModelInstanceEntry)Values[0];
var prevMaterial = value.Material;
if (!material)
{
// Fallback to default material
_materialEditor.Picker.SelectedAsset = defaultMaterial;
value.Material = defaultMaterial;
}
else if (material == slots[_entryIndex].Material)
{
// Asset default material
value.Material = null;
}
else if (material == defaultMaterial && !slots[_entryIndex].Material)
{
// Default material while asset has no set as well
value.Material = null;
}
else
{
// Custom material
value.Material = material;
}
if (prevMaterial != value.Material)
SetValue(value);
_isRefreshing = false;
}
/// <inheritdoc />
protected override void SpawnProperty(LayoutElementsContainer itemLayout, ValueContainer itemValues, ItemInfo item)
{
// Skip material member as it is overridden
if (item.Info.Name == "Material")
if (item.Info.Name == "Material" && _materialEditor != null)
return;
base.SpawnProperty(itemLayout, itemValues, item);
}
@@ -91,6 +112,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc />
public override void Refresh()
{
// Update panel title to match material slot name
if (_updateName &&
_group != null &&
ParentEditor?.ParentEditor != null &&
@@ -102,13 +124,26 @@ namespace FlaxEditor.CustomEditors.Editors
var slots = modelInstance.MaterialSlots;
if (slots != null && slots.Length > entryIndex)
{
_group.Panel.HeaderText = "Entry " + slots[entryIndex].Name;
_updateName = false;
_group.Panel.HeaderText = "Entry " + slots[entryIndex].Name;
}
}
}
// Refresh currently selected material
_material = _modelInstance.GetMaterial(_entryIndex);
base.Refresh();
}
/// <inheritdoc />
protected override void Deinitialize()
{
_material = null;
_modelInstance = null;
_materialEditor = null;
base.Deinitialize();
}
}
}