You're breathtaking!
This commit is contained in:
197
Source/Editor/Surface/AttributesEditor.cs
Normal file
197
Source/Editor/Surface/AttributesEditor.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.CustomEditors.Editors;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace FlaxEditor.Surface
|
||||
{
|
||||
class AttributesEditor : ContextMenuBase
|
||||
{
|
||||
private CustomEditorPresenter _presenter;
|
||||
private byte[] _oldData;
|
||||
|
||||
private class Proxy
|
||||
{
|
||||
[Collection(OverrideEditorTypeName = "FlaxEditor.Surface.AttributesEditor+ValuesEditor", Spacing = 10)]
|
||||
[EditorDisplay(null, EditorDisplayAttribute.InlineStyle)]
|
||||
public Attribute[] Value;
|
||||
}
|
||||
|
||||
public sealed class ValuesEditor : ObjectSwitcherEditor
|
||||
{
|
||||
private OptionType[] _options;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override OptionType[] Options => _options;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var options = (IList<Type>)Presenter.Panel.Tag;
|
||||
_options = new OptionType[options.Count];
|
||||
for (int i = 0; i < options.Count; i++)
|
||||
{
|
||||
var type = options[i];
|
||||
_options[i] = new OptionType(CustomEditorsUtil.GetPropertyNameUI(type.Name), type, Creator);
|
||||
}
|
||||
|
||||
base.Initialize(layout);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
base.Deinitialize();
|
||||
|
||||
_options = null;
|
||||
}
|
||||
|
||||
private object Creator(Type type)
|
||||
{
|
||||
var ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Utils.GetEmptyArray<Type>(), null);
|
||||
return ctor.Invoke(Utils.GetEmptyArray<object>());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The action fired when parameters editing finishes and value gets accepted to be set.
|
||||
/// </summary>
|
||||
public Action<Attribute[]> Edited;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AttributesEditor"/> class.
|
||||
/// </summary>
|
||||
/// <param name="attributes">The attributes list to edit.</param>
|
||||
/// <param name="attributeType">The allowed attribute types to use.</param>
|
||||
public AttributesEditor(Attribute[] attributes, IList<Type> attributeType)
|
||||
{
|
||||
// Context menu dimensions
|
||||
const float width = 340.0f;
|
||||
const float height = 370.0f;
|
||||
Size = new Vector2(width, height);
|
||||
|
||||
// Title
|
||||
var title = new Label(2, 2, width - 4, 23.0f)
|
||||
{
|
||||
Font = new FontReference(Style.Current.FontLarge),
|
||||
Text = "Edit attributes",
|
||||
Parent = this
|
||||
};
|
||||
|
||||
// Buttons
|
||||
float buttonsWidth = (width - 16.0f) * 0.5f;
|
||||
float buttonsHeight = 20.0f;
|
||||
var cancelButton = new Button(4.0f, title.Bottom + 4.0f, buttonsWidth, buttonsHeight)
|
||||
{
|
||||
Text = "Cancel",
|
||||
Parent = this
|
||||
};
|
||||
cancelButton.Clicked += Hide;
|
||||
var okButton = new Button(cancelButton.Right + 4.0f, cancelButton.Y, buttonsWidth, buttonsHeight)
|
||||
{
|
||||
Text = "OK",
|
||||
Parent = this
|
||||
};
|
||||
okButton.Clicked += OnOkButtonClicked;
|
||||
|
||||
// Actual panel
|
||||
var panel1 = new Panel(ScrollBars.Vertical)
|
||||
{
|
||||
Bounds = new Rectangle(0, okButton.Bottom + 4.0f, width, height - okButton.Bottom - 2.0f),
|
||||
Parent = this
|
||||
};
|
||||
var editor = new CustomEditorPresenter(null);
|
||||
editor.Panel.AnchorPreset = AnchorPresets.HorizontalStretchTop;
|
||||
editor.Panel.IsScrollable = true;
|
||||
editor.Panel.Parent = panel1;
|
||||
editor.Panel.Tag = attributeType;
|
||||
_presenter = editor;
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
var formatter = new BinaryFormatter();
|
||||
formatter.Serialize(stream, attributes);
|
||||
_oldData = stream.ToArray();
|
||||
}
|
||||
editor.Select(new Proxy
|
||||
{
|
||||
Value = attributes,
|
||||
});
|
||||
}
|
||||
|
||||
private void OnOkButtonClicked()
|
||||
{
|
||||
var newValue = ((Proxy)_presenter.Selection[0]).Value;
|
||||
for (int i = 0; i < newValue.Length; i++)
|
||||
{
|
||||
if (newValue[i] == null)
|
||||
{
|
||||
MessageBox.Show("One of the attributes is null. Please set it to the valid object.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
var formatter = new BinaryFormatter();
|
||||
formatter.Serialize(stream, newValue);
|
||||
var newData = stream.ToArray();
|
||||
if (!_oldData.SequenceEqual(newData))
|
||||
{
|
||||
Edited?.Invoke(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
Hide();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnShow()
|
||||
{
|
||||
Focus();
|
||||
|
||||
base.OnShow();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Hide()
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
|
||||
Focus(null);
|
||||
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnKeyDown(KeyboardKeys key)
|
||||
{
|
||||
if (key == KeyboardKeys.Escape)
|
||||
{
|
||||
Hide();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnKeyDown(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
_presenter = null;
|
||||
_oldData = null;
|
||||
Edited = null;
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user