2019-10-05 17:25:28 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Syroot.Maths;
|
2019-10-15 21:48:52 +00:00
|
|
|
|
using Toolbox.Library;
|
2019-10-05 17:25:28 +00:00
|
|
|
|
|
|
|
|
|
namespace LayoutBXLYT
|
|
|
|
|
{
|
|
|
|
|
public class LayoutUndoManager
|
|
|
|
|
{
|
|
|
|
|
protected Stack<IRevertAction> undoStack = new Stack<IRevertAction>();
|
|
|
|
|
protected Stack<IRevertAction> redoStack = new Stack<IRevertAction>();
|
|
|
|
|
|
|
|
|
|
public bool HasUndo => undoStack.Count > 0;
|
|
|
|
|
public bool HasRedo => redoStack.Count > 0;
|
|
|
|
|
|
|
|
|
|
public void Undo()
|
|
|
|
|
{
|
|
|
|
|
if (undoStack.Count > 0)
|
|
|
|
|
redoStack.Push(undoStack.Pop().Revert());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Redo()
|
|
|
|
|
{
|
|
|
|
|
if (redoStack.Count > 0)
|
|
|
|
|
undoStack.Push(redoStack.Pop().Revert());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddToUndo(IRevertAction revertable)
|
|
|
|
|
{
|
|
|
|
|
undoStack.Push(revertable);
|
|
|
|
|
redoStack.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public interface IRevertAction
|
|
|
|
|
{
|
|
|
|
|
IRevertAction Revert();
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-05 22:37:28 +00:00
|
|
|
|
public class UndoActionPaneHide : IRevertAction
|
|
|
|
|
{
|
|
|
|
|
private bool hidePane = true;
|
|
|
|
|
public List<BasePane> targetPanes = new List<BasePane>();
|
|
|
|
|
public UndoActionPaneHide(List<BasePane> panes, bool hide = true)
|
|
|
|
|
{
|
|
|
|
|
targetPanes = panes;
|
|
|
|
|
hidePane = hide;
|
|
|
|
|
|
|
|
|
|
foreach (var pane in targetPanes)
|
|
|
|
|
pane.DisplayInEditor = !hidePane;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IRevertAction Revert()
|
|
|
|
|
{
|
|
|
|
|
foreach (var pane in targetPanes)
|
|
|
|
|
pane.DisplayInEditor = hidePane;
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class UndoActionPaneDelete : IRevertAction
|
|
|
|
|
{
|
|
|
|
|
public BxlytHeader layoutFile;
|
2019-10-14 01:02:39 +00:00
|
|
|
|
|
|
|
|
|
public List<BasePane> topMostPanes = new List<BasePane>();
|
2019-10-05 22:37:28 +00:00
|
|
|
|
public List<PaneInfo> targetPanes = new List<PaneInfo>();
|
|
|
|
|
public UndoActionPaneDelete(List<BasePane> panes, BxlytHeader header)
|
|
|
|
|
{
|
|
|
|
|
layoutFile = header;
|
2019-10-14 01:02:39 +00:00
|
|
|
|
GetTopMostPanes(panes, topMostPanes, header.RootPane);
|
|
|
|
|
|
2019-10-05 22:37:28 +00:00
|
|
|
|
for (int i = 0; i < panes.Count; i++)
|
2019-10-14 01:02:39 +00:00
|
|
|
|
targetPanes.Add(new PaneInfo(panes[i], panes[i].Parent));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Loop through each pane in the heiarchy until it finds the first set of panes
|
|
|
|
|
//The topmost panes are only going to be removed for adding with redo to be easier
|
|
|
|
|
private void GetTopMostPanes(List<BasePane> panes, List<BasePane> topMost, BasePane root)
|
|
|
|
|
{
|
|
|
|
|
foreach (var child in root.Childern)
|
|
|
|
|
{
|
|
|
|
|
if (panes.Contains(child))
|
|
|
|
|
topMost.Add(child);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (topMost.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var child in root.Childern)
|
|
|
|
|
GetTopMostPanes(panes, topMost, child);
|
|
|
|
|
}
|
2019-10-05 22:37:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IRevertAction Revert()
|
|
|
|
|
{
|
2019-10-14 01:02:39 +00:00
|
|
|
|
Console.WriteLine("Redo pane remove ");
|
2019-10-05 22:37:28 +00:00
|
|
|
|
for (int i = 0; i < targetPanes.Count; i++)
|
2019-10-14 01:02:39 +00:00
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("mats " + targetPanes[i].Materials.Count);
|
|
|
|
|
|
|
|
|
|
//Try to add any linked materials. If there is none, the list won't add any
|
|
|
|
|
if (targetPanes[i].Materials.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var mat = targetPanes[i].Materials[0];
|
|
|
|
|
var pane = targetPanes[i].Pane;
|
|
|
|
|
|
|
|
|
|
if (pane is IPicturePane)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("IPicturePane pane ");
|
|
|
|
|
|
|
|
|
|
layoutFile.AddMaterial(mat, ((IPicturePane)pane).MaterialIndex);
|
|
|
|
|
((IPicturePane)pane).Material = mat;
|
|
|
|
|
}
|
|
|
|
|
else if (pane is ITextPane)
|
|
|
|
|
{
|
|
|
|
|
layoutFile.AddMaterial(mat, ((ITextPane)pane).MaterialIndex);
|
|
|
|
|
((ITextPane)pane).Material = mat;
|
|
|
|
|
}
|
|
|
|
|
else if (pane is IWindowPane)
|
|
|
|
|
{
|
|
|
|
|
var wnd = pane as IWindowPane;
|
|
|
|
|
layoutFile.AddMaterial(mat, wnd.Content.MaterialIndex);
|
|
|
|
|
wnd.Content.Material = mat;
|
|
|
|
|
for (int m = 0; m < wnd.WindowFrames.Count; m++)
|
|
|
|
|
{
|
|
|
|
|
mat = targetPanes[i].Materials[m + 1];
|
|
|
|
|
|
|
|
|
|
layoutFile.AddMaterial(mat, wnd.WindowFrames[m].MaterialIndex);
|
|
|
|
|
wnd.WindowFrames[m].Material = mat;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Add the panes
|
|
|
|
|
if (!layoutFile.PaneLookup.ContainsKey(targetPanes[i].Pane.Name))
|
|
|
|
|
layoutFile.PaneLookup.Add(targetPanes[i].Pane.Name, targetPanes[i].Pane);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Handle children via topmost list
|
|
|
|
|
foreach (var pane in topMostPanes)
|
|
|
|
|
layoutFile.AddPane(pane, pane.Parent);
|
|
|
|
|
|
2019-10-05 22:37:28 +00:00
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class PaneInfo
|
|
|
|
|
{
|
|
|
|
|
public BasePane Parent;
|
|
|
|
|
public BasePane Pane;
|
|
|
|
|
|
2019-10-14 01:02:39 +00:00
|
|
|
|
public List<BxlytMaterial> Materials = new List<BxlytMaterial>();
|
|
|
|
|
|
2019-10-06 01:15:19 +00:00
|
|
|
|
public PaneInfo(BasePane pane, BasePane parent)
|
2019-10-05 22:37:28 +00:00
|
|
|
|
{
|
|
|
|
|
Pane = pane;
|
2019-10-06 01:15:19 +00:00
|
|
|
|
Parent = parent;
|
2019-10-14 01:02:39 +00:00
|
|
|
|
if (parent == null)
|
|
|
|
|
throw new Exception("parent is null!");
|
|
|
|
|
|
|
|
|
|
//We need to add any materials that the material referenced
|
|
|
|
|
if (pane is IPicturePane)
|
|
|
|
|
Materials.Add(((IPicturePane)pane).Material);
|
|
|
|
|
else if (pane is ITextPane)
|
|
|
|
|
Materials.Add(((ITextPane)pane).Material);
|
|
|
|
|
else if (pane is IWindowPane)
|
|
|
|
|
{
|
|
|
|
|
var wnd = pane as IWindowPane;
|
|
|
|
|
|
|
|
|
|
Materials.Add(wnd.Content.Material);
|
|
|
|
|
foreach (var windowFrame in wnd.WindowFrames)
|
|
|
|
|
Materials.Add(windowFrame.Material);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console.WriteLine($"Pane Undo {pane.Name} {pane} mats " + Materials.Count);
|
2019-10-05 22:37:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-05 17:25:28 +00:00
|
|
|
|
public class UndoActionTransform : IRevertAction
|
|
|
|
|
{
|
2019-10-15 21:48:52 +00:00
|
|
|
|
bool TransformChidlren = false;
|
2019-10-05 17:25:28 +00:00
|
|
|
|
|
2019-10-15 21:48:52 +00:00
|
|
|
|
public List<PaneInfo> Panes = new List<PaneInfo>();
|
2019-10-05 17:25:28 +00:00
|
|
|
|
|
2019-10-15 21:48:52 +00:00
|
|
|
|
public UndoActionTransform(List<BasePane> panes)
|
2019-10-05 17:25:28 +00:00
|
|
|
|
{
|
2019-10-15 21:48:52 +00:00
|
|
|
|
foreach (var pane in panes)
|
|
|
|
|
{
|
|
|
|
|
TransformChidlren = Runtime.LayoutEditor.TransformChidlren;
|
|
|
|
|
Panes.Add(new PaneInfo()
|
|
|
|
|
{
|
|
|
|
|
targetPane = pane,
|
|
|
|
|
Translate = pane.Translate,
|
|
|
|
|
Scale = pane.Scale,
|
|
|
|
|
Rotate = pane.Rotate,
|
|
|
|
|
Width = pane.Width,
|
|
|
|
|
Height = pane.Height,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-05 17:25:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IRevertAction Revert()
|
|
|
|
|
{
|
2019-10-15 21:48:52 +00:00
|
|
|
|
foreach (var pane in Panes)
|
|
|
|
|
{
|
|
|
|
|
if (!TransformChidlren)
|
|
|
|
|
pane.targetPane.KeepChildrenTransform(pane.Translate.X, pane.Translate.Y);
|
|
|
|
|
|
|
|
|
|
pane.targetPane.Translate = pane.Translate;
|
|
|
|
|
pane.targetPane.Scale = pane.Scale;
|
|
|
|
|
pane.targetPane.Rotate = pane.Rotate;
|
|
|
|
|
pane.targetPane.Width = pane.Width;
|
|
|
|
|
pane.targetPane.Height = pane.Height;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-05 17:25:28 +00:00
|
|
|
|
return this;
|
|
|
|
|
}
|
2019-10-15 21:48:52 +00:00
|
|
|
|
|
|
|
|
|
public class PaneInfo
|
|
|
|
|
{
|
|
|
|
|
public Vector3F Translate;
|
|
|
|
|
public Vector3F Rotate;
|
|
|
|
|
public Vector2F Scale;
|
|
|
|
|
|
|
|
|
|
public float Width;
|
|
|
|
|
public float Height;
|
|
|
|
|
|
|
|
|
|
public BasePane targetPane;
|
|
|
|
|
}
|
2019-10-05 17:25:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|