a0e680e626
- Parent origins are now properly applied. Origin values are also correct (were previously being done wrong). - Rotations on X and Y axis now work correctly. - Selection shows a proper bounding if the rotation is rotated on the X or Y axis. - Perspective and orthographic modes can be toggled be tween in the layout editor. Alpha influence is applied properly to picture boxes. Adjustments to bflim loading, so it can load textures without an extension.
413 lines
11 KiB
C#
413 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Syroot.Maths;
|
|
using Toolbox.Library.IO;
|
|
using Toolbox.Library;
|
|
using WeifenLuo.WinFormsUI.Docking;
|
|
using System.ComponentModel;
|
|
|
|
namespace LayoutBXLYT
|
|
{
|
|
public class BasePane : SectionCommon
|
|
{
|
|
public bool IsRoot = false;
|
|
|
|
public bool ParentIsRoot
|
|
{
|
|
get { return Parent != null && Parent.IsRoot; }
|
|
}
|
|
|
|
[DisplayName("Alpha"), CategoryAttribute("Alpha")]
|
|
public byte Alpha { get; set; }
|
|
|
|
[DisplayName("Influence Alpha"), CategoryAttribute("Alpha")]
|
|
public virtual bool InfluenceAlpha { get; set; }
|
|
|
|
[Browsable(false)]
|
|
public virtual bool DisplayInEditor { get; set; } = true;
|
|
|
|
[DisplayName("Name"), CategoryAttribute("Pane")]
|
|
public string Name { get; set; }
|
|
|
|
[DisplayName("Translate"), CategoryAttribute("Pane")]
|
|
public Vector3F Translate { get; set; }
|
|
|
|
[DisplayName("Rotate"), CategoryAttribute("Pane")]
|
|
public Vector3F Rotate { get; set; }
|
|
|
|
[DisplayName("Scale"), CategoryAttribute("Pane")]
|
|
public Vector2F Scale { get; set; }
|
|
|
|
[DisplayName("Width"), CategoryAttribute("Pane")]
|
|
public float Width { get; set; }
|
|
|
|
[DisplayName("Width"), CategoryAttribute("Pane")]
|
|
public float Height { get; set; }
|
|
|
|
[DisplayName("Origin X"), CategoryAttribute("Origin")]
|
|
public virtual OriginX originX { get; set; }
|
|
|
|
[DisplayName("Origin X"), CategoryAttribute("Origin")]
|
|
public virtual OriginY originY { get; set; }
|
|
|
|
[DisplayName("Parent Origin X"), CategoryAttribute("Origin")]
|
|
public virtual OriginX ParentOriginX { get; set; }
|
|
|
|
[DisplayName("Parent Origin Y"), CategoryAttribute("Origin")]
|
|
public virtual OriginY ParentOriginY { get; set; }
|
|
|
|
[Browsable(false)]
|
|
public BasePane Parent { get; set; }
|
|
|
|
[Browsable(false)]
|
|
public List<BasePane> Childern { get; set; } = new List<BasePane>();
|
|
|
|
[Browsable(false)]
|
|
public bool HasChildern
|
|
{
|
|
get { return Childern.Count > 0; }
|
|
}
|
|
|
|
public BasePane()
|
|
{
|
|
originX = OriginX.Center;
|
|
originY = OriginY.Center;
|
|
ParentOriginX = OriginX.Center;
|
|
ParentOriginY = OriginY.Center;
|
|
}
|
|
|
|
private CustomRectangle rectangle;
|
|
public CustomRectangle Rectangle
|
|
{
|
|
get
|
|
{
|
|
UpdateRectangle();
|
|
return rectangle;
|
|
}
|
|
}
|
|
|
|
private void UpdateRectangle() {
|
|
rectangle = CreateRectangle();
|
|
}
|
|
|
|
public CustomRectangle CreateRectangle()
|
|
{
|
|
//Do origin transforms
|
|
var transformed = TransformOrientation((int)Width, (int)Height, originX, originY);
|
|
var parentTransform = ParentOriginTransform(transformed);
|
|
|
|
return new CustomRectangle(
|
|
parentTransform.X,
|
|
parentTransform.Y,
|
|
parentTransform.Z,
|
|
parentTransform.W);
|
|
}
|
|
|
|
//Get the previous transform from the parent origin
|
|
private Vector4 ParentOriginTransform(Vector4 points)
|
|
{
|
|
//Dont shift the root or the first child of the root
|
|
//The parent setting shouldn't be set, but it doesn't hurt to do this
|
|
if (IsRoot || ParentIsRoot || Parent == null)
|
|
return points;
|
|
|
|
var transformedPosition = TransformOrientationPosition((int)Parent.Width, (int)Parent.Height, ParentOriginX, ParentOriginY);
|
|
var transformed = ShiftRectangle(transformedPosition, points);
|
|
if (Parent != null)
|
|
return Parent.ParentOriginTransform(transformed);
|
|
|
|
return transformed;
|
|
}
|
|
|
|
private static Vector4 ShiftRectangle(Vector2 position, Vector4 points)
|
|
{
|
|
int left = points[0] + position.X;
|
|
int right = points[1] + position.X;
|
|
int top = points[2] + position.Y;
|
|
int bottom = points[3] + position.Y;
|
|
return new Vector4(left, right, top, bottom);
|
|
}
|
|
|
|
private static Vector2 TransformOrientationPosition(int Width, int Height, OriginX originX, OriginY originY)
|
|
{
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
if (originX == OriginX.Left)
|
|
x = -(Width / 2);
|
|
else if (originX == OriginX.Right)
|
|
x = (Width / 2);
|
|
|
|
if (originY == OriginY.Top)
|
|
y = Height / 2;
|
|
else if (originY == OriginY.Bottom)
|
|
y = -(Height / 2);
|
|
|
|
return new Vector2(x,y);
|
|
}
|
|
|
|
private static Vector4 TransformOrientation(int Width, int Height, OriginX originX, OriginY originY)
|
|
{
|
|
int left = 0;
|
|
int right = 0;
|
|
int top = 0;
|
|
int bottom = 0;
|
|
|
|
if (originX == OriginX.Left)
|
|
right = Width;
|
|
else if (originX == OriginX.Right)
|
|
left = -Width;
|
|
else //To center
|
|
{
|
|
left = -Width / 2;
|
|
right = Width / 2;
|
|
}
|
|
|
|
if (originY == OriginY.Top)
|
|
bottom = Height;
|
|
else if (originY == OriginY.Bottom)
|
|
top = -Height;
|
|
else //To center
|
|
{
|
|
top = -Height / 2;
|
|
bottom = Height / 2;
|
|
}
|
|
|
|
return new Vector4(left, right, top, bottom);
|
|
}
|
|
|
|
public bool IsHit(int X, int Y)
|
|
{
|
|
if ((X > Translate.X) && (X < Translate.X + Width) &&
|
|
(Y > Translate.Y) && (Y < Translate.Y + Height))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public enum OriginX : byte
|
|
{
|
|
Center = 0,
|
|
Left = 1,
|
|
Right = 2
|
|
};
|
|
|
|
public enum OriginY : byte
|
|
{
|
|
Center = 0,
|
|
Top = 1,
|
|
Bottom = 2
|
|
};
|
|
|
|
public interface IUserDataContainer
|
|
{
|
|
UserData UserData { get; set; }
|
|
}
|
|
|
|
public class UserData : SectionCommon
|
|
{
|
|
public List<UserDataEntry> Entries { get; set; }
|
|
|
|
public UserData()
|
|
{
|
|
Entries = new List<UserDataEntry>();
|
|
}
|
|
|
|
public override void Write(FileWriter writer, BxlytHeader header)
|
|
{
|
|
}
|
|
}
|
|
|
|
public class UserDataEntry
|
|
{
|
|
public string Name { get; set; }
|
|
public UserDataType Type { get; set; }
|
|
public byte Unknown { get; set; }
|
|
|
|
public object data;
|
|
|
|
public string GetString()
|
|
{
|
|
return (string)data;
|
|
}
|
|
|
|
public float[] GetFloats()
|
|
{
|
|
return (float[])data;
|
|
}
|
|
|
|
public int[] GetInts()
|
|
{
|
|
return (int[])data;
|
|
}
|
|
|
|
public void SetValue(string value)
|
|
{
|
|
data = value;
|
|
Type = UserDataType.String;
|
|
}
|
|
|
|
public void SetValue(float[] value)
|
|
{
|
|
data = value;
|
|
Type = UserDataType.Float;
|
|
}
|
|
|
|
public void SetValue(int[] value)
|
|
{
|
|
data = value;
|
|
Type = UserDataType.Int;
|
|
}
|
|
|
|
internal long _pos;
|
|
}
|
|
|
|
public enum UserDataType : byte
|
|
{
|
|
String,
|
|
Int,
|
|
Float,
|
|
}
|
|
|
|
public class BxlytHeader : IDisposable
|
|
{
|
|
[Browsable(false)]
|
|
public string FileName
|
|
{
|
|
get { return FileInfo.FileName; }
|
|
}
|
|
|
|
[DisplayName("Use Big Endian"), CategoryAttribute("File Settings")]
|
|
public bool IsBigEndian { get; set; }
|
|
|
|
[Browsable(false)]
|
|
internal IFileFormat FileInfo;
|
|
|
|
[Browsable(false)]
|
|
public BasePane RootPane { get; set; }
|
|
|
|
[Browsable(false)]
|
|
public BasePane RootGroup { get; set; }
|
|
|
|
[Browsable(false)]
|
|
public virtual Dictionary<string, STGenericTexture> GetTextures { get; }
|
|
|
|
[Browsable(false)]
|
|
public virtual List<string> Textures { get; }
|
|
|
|
[Browsable(false)]
|
|
public virtual List<string> Fonts { get; }
|
|
|
|
[Browsable(false)]
|
|
internal uint Version;
|
|
|
|
[DisplayName("Version"), CategoryAttribute("File Settings")]
|
|
public string VersionFull
|
|
{
|
|
get
|
|
{
|
|
return $"{VersionMajor},{VersionMinor},{VersionMicro},{VersionMicro2}";
|
|
}
|
|
}
|
|
|
|
[Browsable(false)]
|
|
public virtual List<BxlytMaterial> GetMaterials()
|
|
{
|
|
return new List<BxlytMaterial>();
|
|
}
|
|
|
|
[RefreshProperties(RefreshProperties.All)]
|
|
public uint VersionMajor { get; set; }
|
|
[RefreshProperties(RefreshProperties.All)]
|
|
public uint VersionMinor { get; set; }
|
|
[RefreshProperties(RefreshProperties.All)]
|
|
public uint VersionMicro { get; set; }
|
|
[RefreshProperties(RefreshProperties.All)]
|
|
public uint VersionMicro2 { get; set; }
|
|
|
|
internal void SetVersionInfo()
|
|
{
|
|
VersionMajor = Version >> 24;
|
|
VersionMinor = Version >> 16 & 0xFF;
|
|
VersionMicro = Version >> 8 & 0xFF;
|
|
VersionMicro2 = Version & 0xFF;
|
|
}
|
|
|
|
internal uint SaveVersion()
|
|
{
|
|
return VersionMajor << 24 | VersionMinor << 16 | VersionMicro << 8 | VersionMicro2;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
FileInfo.Unload();
|
|
}
|
|
}
|
|
|
|
public class BxlytMaterial
|
|
{
|
|
[DisplayName("Name"), CategoryAttribute("General")]
|
|
public virtual string Name { get; set; }
|
|
}
|
|
|
|
public class SectionCommon
|
|
{
|
|
public virtual string Signature { get; }
|
|
public uint SectionSize { get; set; }
|
|
public long StartPosition { get; set; }
|
|
|
|
internal byte[] Data { get; set; }
|
|
|
|
public SectionCommon()
|
|
{
|
|
|
|
}
|
|
|
|
public SectionCommon(string signature)
|
|
{
|
|
Signature = signature;
|
|
}
|
|
|
|
public virtual void Write(FileWriter writer, BxlytHeader header)
|
|
{
|
|
if (Data != null)
|
|
writer.Write(Data);
|
|
}
|
|
}
|
|
|
|
public class CustomRectangle
|
|
{
|
|
public int LeftPoint;
|
|
public int RightPoint;
|
|
public int TopPoint;
|
|
public int BottomPoint;
|
|
|
|
public CustomRectangle(int left, int right, int top, int bottom)
|
|
{
|
|
LeftPoint = left;
|
|
RightPoint = right;
|
|
TopPoint = top;
|
|
BottomPoint = bottom;
|
|
}
|
|
|
|
public float Width
|
|
{
|
|
get { return LeftPoint - RightPoint; }
|
|
}
|
|
|
|
public float Height
|
|
{
|
|
get { return TopPoint - BottomPoint; }
|
|
}
|
|
}
|
|
|
|
public class LayoutDocked : DockContent
|
|
{
|
|
|
|
}
|
|
}
|