269 lines
7.2 KiB
C#
269 lines
7.2 KiB
C#
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
|
|
using FlaxEditor.Content;
|
|
using FlaxEditor.GUI;
|
|
using FlaxEditor.Surface;
|
|
using FlaxEngine;
|
|
using FlaxEngine.GUI;
|
|
|
|
namespace FlaxEditor.Windows.Assets
|
|
{
|
|
/// <summary>
|
|
/// The base class for editor windows that use <see cref="FlaxEditor.Surface.VisjectSurface"/> for content editing by graph functions (eg. material functions, particle emitter functions).
|
|
/// </summary>
|
|
/// <seealso cref="FlaxEditor.Windows.Assets.AssetEditorWindow" />
|
|
/// <seealso cref="FlaxEditor.Surface.IVisjectSurfaceOwner" />
|
|
public abstract class VisjectFunctionSurfaceWindow<TAsset, TSurface> : ClonedAssetEditorWindowBase<TAsset>, IVisjectSurfaceOwner
|
|
where TAsset : Asset
|
|
where TSurface : VisjectSurface
|
|
{
|
|
/// <summary>
|
|
/// The surface.
|
|
/// </summary>
|
|
protected TSurface _surface;
|
|
|
|
/// <summary>
|
|
/// The panel for the surface.
|
|
/// </summary>
|
|
protected readonly Panel _panel;
|
|
|
|
private readonly ToolStripButton _saveButton;
|
|
private readonly ToolStripButton _undoButton;
|
|
private readonly ToolStripButton _redoButton;
|
|
private bool _showWholeGraphOnLoad = true;
|
|
|
|
/// <summary>
|
|
/// True if temporary asset is dirty, otherwise false.
|
|
/// </summary>
|
|
protected bool _tmpAssetIsDirty;
|
|
|
|
/// <summary>
|
|
/// True if window is waiting for asset load to load surface.
|
|
/// </summary>
|
|
protected bool _isWaitingForSurfaceLoad;
|
|
|
|
/// <summary>
|
|
/// The undo.
|
|
/// </summary>
|
|
protected Undo _undo;
|
|
|
|
/// <summary>
|
|
/// Gets the Visject Surface.
|
|
/// </summary>
|
|
public TSurface Surface => _surface;
|
|
|
|
/// <summary>
|
|
/// Gets the undo history context for this window.
|
|
/// </summary>
|
|
public Undo Undo => _undo;
|
|
|
|
/// <inheritdoc />
|
|
protected VisjectFunctionSurfaceWindow(Editor editor, AssetItem item)
|
|
: base(editor, item)
|
|
{
|
|
var inputOptions = Editor.Options.Options.Input;
|
|
|
|
// Undo
|
|
_undo = new Undo();
|
|
_undo.UndoDone += OnUndoRedo;
|
|
_undo.RedoDone += OnUndoRedo;
|
|
_undo.ActionDone += OnUndoRedo;
|
|
|
|
// Toolstrip
|
|
SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton);
|
|
|
|
// Panel
|
|
_panel = new Panel(ScrollBars.None)
|
|
{
|
|
AnchorPreset = AnchorPresets.StretchAll,
|
|
Offsets = new Margin(0, 0, _toolstrip.Bottom, 0),
|
|
Parent = this
|
|
};
|
|
}
|
|
|
|
private void OnUndoRedo(IUndoAction action)
|
|
{
|
|
MarkAsEdited();
|
|
UpdateToolstrip();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows the whole surface graph.
|
|
/// </summary>
|
|
public void ShowWholeGraph()
|
|
{
|
|
_surface.ShowWholeGraph();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refreshes temporary asset to see changes live when editing the surface.
|
|
/// </summary>
|
|
/// <returns>True if cannot refresh it, otherwise false.</returns>
|
|
public bool RefreshTempAsset()
|
|
{
|
|
// Early check
|
|
if (_asset == null || _isWaitingForSurfaceLoad)
|
|
return true;
|
|
|
|
// Check if surface has been edited
|
|
if (_surface.IsEdited)
|
|
{
|
|
return SaveSurface();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void Save()
|
|
{
|
|
if (!IsEdited)
|
|
return;
|
|
|
|
if (RefreshTempAsset())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (SaveToOriginal())
|
|
{
|
|
return;
|
|
}
|
|
|
|
ClearEditedFlag();
|
|
OnSurfaceEditedChanged();
|
|
_item.RefreshThumbnail();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void UpdateToolstrip()
|
|
{
|
|
_saveButton.Enabled = IsEdited;
|
|
_undoButton.Enabled = _undo.CanUndo;
|
|
_redoButton.Enabled = _undo.CanRedo;
|
|
|
|
base.UpdateToolstrip();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void UnlinkItem()
|
|
{
|
|
_isWaitingForSurfaceLoad = false;
|
|
|
|
base.UnlinkItem();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void OnAssetLinked()
|
|
{
|
|
_isWaitingForSurfaceLoad = true;
|
|
|
|
base.OnAssetLinked();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public Asset SurfaceAsset => Asset;
|
|
|
|
/// <inheritdoc />
|
|
public abstract string SurfaceName { get; }
|
|
|
|
/// <inheritdoc />
|
|
public abstract byte[] SurfaceData { get; set; }
|
|
|
|
/// <inheritdoc />
|
|
public VisjectSurfaceContext ParentContext => null;
|
|
|
|
/// <inheritdoc />
|
|
public void OnContextCreated(VisjectSurfaceContext context)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void OnSurfaceEditedChanged()
|
|
{
|
|
if (_surface.IsEdited)
|
|
MarkAsEdited();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void OnSurfaceGraphEdited()
|
|
{
|
|
// Mark as dirty
|
|
_tmpAssetIsDirty = true;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void OnSurfaceClose()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads the surface from the asset. Called during <see cref="Update"/> when asset is loaded and surface is missing.
|
|
/// </summary>
|
|
/// <returns>True if failed, otherwise false.</returns>
|
|
protected virtual bool LoadSurface()
|
|
{
|
|
if (_surface.Load())
|
|
{
|
|
Editor.LogError("Failed to load surface.");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the surface to the asset. Called during <see cref="Update"/> when asset is loaded and surface is missing.
|
|
/// </summary>
|
|
/// <returns>True if failed, otherwise false.</returns>
|
|
protected virtual bool SaveSurface()
|
|
{
|
|
_surface.Save();
|
|
return false;
|
|
}
|
|
|
|
|
|
/// <inheritdoc />
|
|
public override void Update(float deltaTime)
|
|
{
|
|
base.Update(deltaTime);
|
|
|
|
if (_tmpAssetIsDirty)
|
|
{
|
|
_tmpAssetIsDirty = false;
|
|
|
|
RefreshTempAsset();
|
|
}
|
|
|
|
if (_isWaitingForSurfaceLoad && _asset.IsLoaded)
|
|
{
|
|
_isWaitingForSurfaceLoad = false;
|
|
|
|
if (LoadSurface())
|
|
{
|
|
Close();
|
|
return;
|
|
}
|
|
|
|
// Setup
|
|
_undo.Clear();
|
|
_surface.Enabled = true;
|
|
ClearEditedFlag();
|
|
if (_showWholeGraphOnLoad)
|
|
{
|
|
_showWholeGraphOnLoad = false;
|
|
_surface.ShowWholeGraph();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void OnDestroy()
|
|
{
|
|
_undo.Clear();
|
|
|
|
base.OnDestroy();
|
|
}
|
|
}
|
|
}
|