diff --git a/Source/Editor/Windows/Assets/JsonAssetWindow.cs b/Source/Editor/Windows/Assets/JsonAssetWindow.cs index 86cf78ffc..43b34a8c6 100644 --- a/Source/Editor/Windows/Assets/JsonAssetWindow.cs +++ b/Source/Editor/Windows/Assets/JsonAssetWindow.cs @@ -4,8 +4,11 @@ using System; using FlaxEditor.Content; using FlaxEditor.CustomEditors; using FlaxEditor.GUI; +using FlaxEditor.GUI.ContextMenu; using FlaxEngine; using FlaxEngine.GUI; +using FlaxEngine.Json; +using FlaxEngine.Utilities; namespace FlaxEditor.Windows.Assets { @@ -16,6 +19,53 @@ namespace FlaxEditor.Windows.Assets /// public sealed class JsonAssetWindow : AssetEditorWindowBase { + private class ObjectPasteUndo : IUndoAction + { + /// + public string ActionString => "Object Paste Undo"; + + private JsonAssetWindow _window; + private string _oldObject; + private string _newObject; + + public ObjectPasteUndo(object oldObject, object newObject, JsonAssetWindow window) + { + _oldObject = JsonSerializer.Serialize(oldObject); + _newObject = JsonSerializer.Serialize(newObject); + _window = window; + } + + /// + public void Dispose() + { + _oldObject = null; + _newObject = null; + _window = null; + } + + /// + public void Do() + { + if (!string.IsNullOrEmpty(_newObject)) + { + _window._object = JsonSerializer.Deserialize(_newObject, TypeUtils.GetType(_window.Asset.DataTypeName).Type); + _window.MarkAsEdited(); + _window._presenter.Select(_window._object); + } + } + + /// + public void Undo() + { + if (!string.IsNullOrEmpty(_oldObject)) + { + _window._object = JsonSerializer.Deserialize(_oldObject, TypeUtils.GetType(_window.Asset.DataTypeName).Type); + _window.MarkAsEdited(); + _window._presenter.Select(_window._object); + } + } + } + private readonly CustomEditorPresenter _presenter; private readonly ToolStripButton _saveButton; private readonly ToolStripButton _undoButton; @@ -24,6 +74,8 @@ namespace FlaxEditor.Windows.Assets private object _object; private bool _isRegisteredForScriptsReload; private Label _typeText; + private ToolStripButton _optionsButton; + private ContextMenu _optionsCM; /// /// Gets the instance of the Json asset object that is being edited. @@ -139,6 +191,30 @@ namespace FlaxEditor.Windows.Assets if (_typeText != null) _typeText.Dispose(); + + // Get content item for options button + object buttonTag = null; + var allTypes = Editor.CodeEditing.All.Get(); + foreach (var type in allTypes) + { + if (type.TypeName.Equals(Asset.DataTypeName, StringComparison.Ordinal)) + { + buttonTag = type.ContentItem; + break; + } + } + + _optionsButton = new ToolStripButton(_toolstrip.ItemsHeight, ref Editor.Icons.Settings12) + { + AnchorPreset = AnchorPresets.TopRight, + Tag = buttonTag, + Size = new Float2(18), + Parent = this, + }; + _optionsButton.LocalX -= (_optionsButton.Width + 4); + _optionsButton.LocalY += (_toolstrip.Height - _optionsButton.Height) * 0.5f; + _optionsButton.Clicked += OpenOptionsContextMenu; + var typeText = new ClickableLabel { Text = $"{Asset.DataTypeName}", @@ -147,9 +223,8 @@ namespace FlaxEditor.Windows.Assets AutoWidth = true, Parent = this, }; - typeText.LocalX += -(typeText.Width + 4); + typeText.LocalX += -(typeText.Width + _optionsButton.Width + 8); typeText.LocalY += (_toolstrip.Height - typeText.Height) * 0.5f; - typeText.RightClick = () => Clipboard.Text = Asset.DataTypeName; _typeText = typeText; _undo.Clear(); @@ -165,6 +240,62 @@ namespace FlaxEditor.Windows.Assets base.OnAssetLoaded(); } + private void OpenOptionsContextMenu() + { + if (_optionsCM != null && _optionsCM.ContainsFocus) + return; + + _optionsCM = new ContextMenu(); + _optionsCM.AddButton("Copy type name", () => Clipboard.Text = Asset.DataTypeName); + _optionsCM.AddButton("Copy asset data", () => Clipboard.Text = Asset.Data); + _optionsCM.AddButton("Paste asset data", () => + { + if (!string.IsNullOrEmpty(Clipboard.Text)) + { + var dataTypeName = Asset.DataTypeName; + var type = TypeUtils.GetType(dataTypeName); + if (type != null) + { + try + { + var obj = Activator.CreateInstance(type.Type); + var data = Clipboard.Text; + JsonSerializer.Deserialize(obj, data); + if (obj != null) + { + var undoAction = new ObjectPasteUndo(_object, obj, this); + undoAction.Do(); + _undo.AddAction(undoAction); + } + else + { + Editor.LogWarning("Pasted data is not the correct data type or has incomplete data"); + } + } + catch (Exception ex) + { + Editor.LogWarning($"Pasted data is not the correct data type or has incomplete data. Exception: {ex}"); + } + } + } + }); + _optionsCM.Enabled = !string.IsNullOrEmpty(Clipboard.Text); + _optionsCM.AddSeparator(); + if (_optionsButton.Tag is ContentItem item) + { + _optionsCM.AddButton("Edit asset code", () => + { + Editor.Instance.ContentEditing.Open(item); + }); + _optionsCM.AddButton("Show asset code item in content window", () => + { + Editor.Instance.Windows.ContentWin.Select(item); + }); + } + + _optionsCM.Show(_optionsButton, _optionsButton.PointFromScreen(Input.MouseScreenPosition)); + } + /// protected override void OnAssetLoadFailed() {