Some more bug fixes

Fixed hit detection if the pane has custom scaling.
Improve multi selection for panes (uses one selection box)
Improve selecting (ctrl can be used properly to multi select, and mosue clicking already selected panes will allow dragging.
Fix hash only sarcs to auto generate if name changed or new files added.
Fixed texture folders for newly added textures for layouts
This commit is contained in:
KillzXGaming 2019-10-15 17:48:52 -04:00
parent 137cbc2bbb
commit 0882c488c9
12 changed files with 400 additions and 271 deletions

View file

@ -250,22 +250,7 @@ namespace FirstPlugin
file.SaveFileFormat();
if (sarcData.HashOnly)
{
sarcData.Files.Add(file.HashName, file.FileData);
/*
uint hash = 0;
bool IsHash = uint.TryParse(file.FileName, out hash);
if (IsHash && file.FileName.Length == 8)
{
sarcData.Files.Add(file.FileName, file.FileData);
}
else
{
string Hash = Crc32.Compute(file.FileName).ToString();
sarcData.Files.Add(Hash, file.FileData);
}*/
}
else
sarcData.Files.Add(file.FileName, file.FileData);
}
@ -283,7 +268,54 @@ namespace FirstPlugin
{
public SARC sarc; //Sarc file the entry is located in
public string HashName;
public string OriginalFileName;
private bool NameChanged
{
get { return OriginalFileName != FileName; }
}
private string hashName;
public string HashName
{
get
{
if (hashName == null || NameChanged)
hashName = NameHash(FileName).ToString("X");
return hashName;
}
set
{
hashName = value;
}
}
public bool IsHashMatch(string fileName)
{
uint hash = StringHashToUint(hashName);
return hash == NameHash(FileName);
}
static uint NameHash(string name)
{
uint result = 0;
for (int i = 0; i < name.Length; i++)
{
result = name[i] + result * 0x00000065;
}
return result;
}
static uint StringHashToUint(string name)
{
if (name.Contains("."))
name = name.Split('.')[0];
if (name.Length != 8) throw new Exception("Invalid hash length");
return Convert.ToUInt32(name, 16);
}
public SarcEntry()
{
@ -310,6 +342,7 @@ namespace FirstPlugin
public SarcEntry SetupFileEntry(string fullName, byte[] data, string HashName)
{
SarcEntry sarcEntry = new SarcEntry();
sarcEntry.OriginalFileName = fullName;
sarcEntry.FileName = fullName;
sarcEntry.FileData = data;
sarcEntry.HashName = HashName;

View file

@ -461,10 +461,10 @@ namespace LayoutBXLYT
if (window.Content.TexCoords.Count > 0)
{
texCoords = new Vector2[] {
window.Content.TexCoords[0].BottomLeft.ToTKVector2(),
window.Content.TexCoords[0].BottomRight.ToTKVector2(),
window.Content.TexCoords[0].TopRight.ToTKVector2(),
window.Content.TexCoords[0].TopLeft.ToTKVector2(),
window.Content.TexCoords[0].TopRight.ToTKVector2(),
window.Content.TexCoords[0].BottomRight.ToTKVector2(),
window.Content.TexCoords[0].BottomLeft.ToTKVector2(),
};
}
@ -963,66 +963,11 @@ namespace LayoutBXLYT
break;
}
//Lastly draw a selection box if selected
if (isSelected)
{
if (!Runtime.LayoutEditor.IsGamePreview && !gameWindow)
DrawSelectionBox(pane, isSelected);
}
GL.Disable(EnableCap.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.UseProgram(0);
}
public static void DrawSelectionBox(BasePane pane, bool isSelected)
{
var rect = pane.CreateRectangle();
rect = rect.RotateZ(pane.Rotate.Z);
GL.Disable(EnableCap.Blend);
GL.Disable(EnableCap.AlphaTest);
GL.Disable(EnableCap.Texture2D);
GL.UseProgram(0);
GL.Begin(PrimitiveType.LineLoop);
GL.Color4(isSelected ? Color.Red : Color.Green);
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.TopPoint);
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
if (isSelected)
{
var transformed = rect;
var leftTop = new Vector2(transformed.LeftPoint, transformed.TopPoint);
var left = new Vector2(transformed.LeftPoint, (transformed.BottomPoint + transformed.TopPoint) / 2);
var leftBottom = new Vector2(transformed.LeftPoint, transformed.BottomPoint);
var rightTop = new Vector2(transformed.RightPoint, transformed.TopPoint);
var right = new Vector2(transformed.RightPoint, (transformed.BottomPoint + transformed.TopPoint) / 2);
var rightBottom = new Vector2(transformed.RightPoint, transformed.BottomPoint);
var top = new Vector2((transformed.RightPoint + transformed.LeftPoint) / 2, transformed.TopPoint);
var bottom = new Vector2((transformed.RightPoint + transformed.LeftPoint) / 2, transformed.BottomPoint);
DrawEdgeSquare(leftTop);
DrawEdgeSquare(left);
DrawEdgeSquare(leftBottom);
DrawEdgeSquare(rightTop);
DrawEdgeSquare(right);
DrawEdgeSquare(rightBottom);
DrawEdgeSquare(top);
DrawEdgeSquare(bottom);
}
GL.Enable(EnableCap.Blend);
GL.Enable(EnableCap.AlphaTest);
GL.Enable(EnableCap.Texture2D);
}
private static void GetTextureSize(BxlytMaterial pane, Dictionary<string, STGenericTexture> Textures, out float width, out float height)
{
width = 0;
@ -1395,11 +1340,6 @@ namespace LayoutBXLYT
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
}
if (!gameWindow)
{
DrawSelectionBox(pane, selectionOutline);
}
}
else
{
@ -1416,18 +1356,5 @@ namespace LayoutBXLYT
// pane.renderablePane.Render(vertices, vertexColors, texCoords);
}
}
private static void DrawEdgeSquare(Vector2 position)
{
float scale = 5;
GL.Begin(PrimitiveType.LineLoop);
GL.Color4(Color.Red);
GL.Vertex2(position.X + -1 * scale, position.Y + -1 * scale);
GL.Vertex2(position.X + 1 * scale, position.Y + -1 * scale);
GL.Vertex2(position.X + 1 * scale, position.Y + 1 * scale);
GL.Vertex2(position.X + -1 * scale, position.Y + 1 * scale);
GL.End();
}
}
}

View file

@ -163,6 +163,24 @@ namespace LayoutBXLYT
}
}
public void KeepChildrenTransform(float newTransX, float newTransY)
{
Vector2F distance = new Vector2F(newTransX - Translate.X, newTransY - Translate.Y);
KeepChildrenTransform(distance);
}
private void KeepChildrenTransform(Vector2F distance)
{
if (HasChildern)
{
foreach (var child in Childern)
{
child.Translate -= new Vector3F(distance.X, distance.Y, 0);
child.KeepChildrenTransform(distance);
}
}
}
public CustomRectangle TransformParent(CustomRectangle rect)
{
return rect.GetTransformedRectangle(Parent, Translate,Rotate, Scale);
@ -198,13 +216,28 @@ namespace LayoutBXLYT
parentTransform.W);
}
public void TransformRectangle(LayoutViewer.PickAction pickAction, float pickMouseX, float pickMouseY)
public void TransformRectangle(LayoutViewer.PickAction pickAction, CustomRectangle selectionBox, float pickMouseX, float pickMouseY)
{
CustomRectangle currentRectangle = this.CreateRectangle();
currentRectangle = currentRectangle.GetTransformedRectangle(Parent, Translate, Rotate, Scale);
//The selection box can have mutlile panes selected in one box
//Scaling the edges will have different distances
float distanceLeft = selectionBox.LeftPoint - currentRectangle.LeftPoint;
float distanceRight = selectionBox.RightPoint - currentRectangle.RightPoint;
float distanceTop = selectionBox.TopPoint - currentRectangle.TopPoint;
float distanceBottom = selectionBox.BottomPoint - currentRectangle.BottomPoint;
Console.WriteLine("distanceLeft " + distanceLeft);
Console.WriteLine("distanceRight " + distanceRight);
Console.WriteLine("distanceTop " + distanceTop);
Console.WriteLine("distanceBottom " + distanceBottom);
float posX = Translate.X;
float posY = Translate.Y;
float posZ = Translate.Z;
Console.WriteLine("pickMouseX " + pickMouseX);
float pickWidth = pickMouseX;
float pickHeight = pickMouseY;
@ -1826,6 +1859,11 @@ namespace LayoutBXLYT
double cosTheta = Math.Cos(angleInRadians);
double sinTheta = Math.Sin(angleInRadians);
var centerPoint = new OpenTK.Vector2(0,0);
return new OpenTK.Vector2(
(int)(p1 * cosTheta - p2 * sinTheta),
(int)(p1 * sinTheta + p2 * cosTheta));
return new OpenTK.Vector2(
(int)
(cosTheta * (p1 - centerPoint.X) -
@ -1835,14 +1873,14 @@ namespace LayoutBXLYT
cosTheta * (p2 - centerPoint.Y) + centerPoint.Y));
}
public CustomRectangle GetTransformedRectangle(BasePane parent, Vector3F Transform, Vector3F Rotate, Vector2F Scale)
public CustomRectangle GetTransformedRectangle(BasePane parent, Vector3F Transform, Vector3F Rotate, Vector2F scale)
{
var rect = this.RotateZ(Rotate.Z);
rect = new CustomRectangle(
(int)(rect.LeftPoint + Transform.X * Scale.X),
(int)(rect.RightPoint + Transform.X * Scale.X),
(int)(rect.TopPoint + Transform.Y * Scale.Y),
(int)(rect.BottomPoint + Transform.Y * Scale.Y));
(int)(((rect.LeftPoint * scale.X) + Transform.X)),
(int)(((rect.RightPoint * scale.X) + Transform.X)),
(int)(((rect.TopPoint * scale.Y) + Transform.Y)),
(int)(((rect.BottomPoint * scale.Y) + Transform.Y)));
if (parent != null)
return parent.TransformParent(rect);
@ -1850,12 +1888,12 @@ namespace LayoutBXLYT
return rect;
}
public float Width
public int Width
{
get { return LeftPoint - RightPoint; }
}
public float Height
public int Height
{
get { return TopPoint - BottomPoint; }
}

View file

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using Toolbox.Library;
using FirstPlugin;
@ -102,6 +102,11 @@ namespace LayoutBXLYT
var archive = ArchiveParent;
if (archive == null) return null;
var matches = archive.Files.Where(p => p.FileName.Contains("bflim")).ToList();
string textureFolder = "timg";
if (matches.Count > 0)
textureFolder = System.IO.Path.GetDirectoryName(matches[0].FileName);
var bflim = BFLIM.CreateNewFromImage();
if (bflim == null)
@ -114,7 +119,7 @@ namespace LayoutBXLYT
archive.AddFile(new ArchiveFileInfo()
{
FileData = mem.ToArray(),
FileName = bflim.Text,
FileName = System.IO.Path.Combine(textureFolder, bflim.Text).Replace('\\','/'),
});
}
break;

View file

@ -166,7 +166,7 @@ namespace LayoutBXLYT
expandCB.SelectedItem = texMap.MaxFilterMode;
shrinkCB.SelectedItem = texMap.MinFilterMode;
if (ActiveMaterial.TextureTransforms.Length > SelectedIndex)
if (ActiveMaterial.TextureTransforms?.Length > SelectedIndex)
{
var transform = ActiveMaterial.TextureTransforms[SelectedIndex];
scaleXUD.Value = transform.Scale.X;

View file

@ -125,7 +125,7 @@ namespace LayoutBXLYT
if (isHorizintal)
{
switch (pane.WindowFrames.Count)
switch (pane.FrameCount)
{
case 1:
frameNumCB.SelectedIndex = 0;
@ -137,7 +137,7 @@ namespace LayoutBXLYT
}
else
{
switch (pane.WindowFrames.Count)
switch (pane.FrameCount)
{
case 1:
frameNumCB.SelectedIndex = 0;
@ -194,6 +194,22 @@ namespace LayoutBXLYT
{
if (!loaded) return;
if (ActivePane.WindowKind != WindowKind.Around)
{
switch (frameNumCB.SelectedIndex)
{
case 0:
ActivePane.FrameCount = 1;
windowFrameSelector1.FrameCount = 1;
break;
case 1:
ActivePane.FrameCount = 2;
windowFrameSelector1.FrameCount = 2;
break;
}
}
else
{
switch (frameNumCB.SelectedIndex)
{
case 0:
@ -209,6 +225,7 @@ namespace LayoutBXLYT
windowFrameSelector1.FrameCount = 8;
break;
}
}
ActivePane.ReloadFrames();

View file

@ -52,6 +52,7 @@
this.displayGridToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.textureListToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.textConverterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewPartsAsNullPanesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.orthographicViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.displayNullPanesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.displayyBoundryPanesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -62,7 +63,8 @@
this.resetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.windowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showGameWindowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewPartsAsNullPanesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.panesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.transformChildrenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)(this.backColorDisplay)).BeginInit();
this.stToolStrip1.SuspendLayout();
this.stMenuStrip1.SuspendLayout();
@ -124,6 +126,7 @@
//
// stToolStrip1
//
this.stToolStrip1.HighlightSelectedTab = false;
this.stToolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripButton1,
this.toolstripOrthoBtn});
@ -155,6 +158,7 @@
//
// stMenuStrip1
//
this.stMenuStrip1.HighlightSelectedTab = false;
this.stMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.editToolStripMenuItem,
@ -218,7 +222,8 @@
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.undoToolStripMenuItem,
this.redoToolStripMenuItem});
this.redoToolStripMenuItem,
this.panesToolStripMenuItem});
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20);
this.editToolStripMenuItem.Text = "Edit";
@ -226,14 +231,14 @@
// undoToolStripMenuItem
//
this.undoToolStripMenuItem.Name = "undoToolStripMenuItem";
this.undoToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
this.undoToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.undoToolStripMenuItem.Text = "Undo";
this.undoToolStripMenuItem.Click += new System.EventHandler(this.undoToolStripMenuItem_Click);
//
// redoToolStripMenuItem
//
this.redoToolStripMenuItem.Name = "redoToolStripMenuItem";
this.redoToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
this.redoToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.redoToolStripMenuItem.Text = "Redo";
this.redoToolStripMenuItem.Click += new System.EventHandler(this.redoToolStripMenuItem_Click);
//
@ -285,6 +290,14 @@
this.textConverterToolStripMenuItem.Text = "Text Converter";
this.textConverterToolStripMenuItem.Click += new System.EventHandler(this.textConverterToolStripMenuItem_Click);
//
// viewPartsAsNullPanesToolStripMenuItem
//
this.viewPartsAsNullPanesToolStripMenuItem.CheckOnClick = true;
this.viewPartsAsNullPanesToolStripMenuItem.Name = "viewPartsAsNullPanesToolStripMenuItem";
this.viewPartsAsNullPanesToolStripMenuItem.Size = new System.Drawing.Size(203, 22);
this.viewPartsAsNullPanesToolStripMenuItem.Text = "View Parts As Null Panes";
this.viewPartsAsNullPanesToolStripMenuItem.Click += new System.EventHandler(this.viewPartsAsNullPanesToolStripMenuItem_Click);
//
// orthographicViewToolStripMenuItem
//
this.orthographicViewToolStripMenuItem.Checked = true;
@ -375,13 +388,21 @@
this.showGameWindowToolStripMenuItem.Text = "Show Game Window";
this.showGameWindowToolStripMenuItem.Click += new System.EventHandler(this.showGameWindowToolStripMenuItem_Click);
//
// viewPartsAsNullPanesToolStripMenuItem
// panesToolStripMenuItem
//
this.viewPartsAsNullPanesToolStripMenuItem.CheckOnClick = true;
this.viewPartsAsNullPanesToolStripMenuItem.Name = "viewPartsAsNullPanesToolStripMenuItem";
this.viewPartsAsNullPanesToolStripMenuItem.Size = new System.Drawing.Size(203, 22);
this.viewPartsAsNullPanesToolStripMenuItem.Text = "View Parts As Null Panes";
this.viewPartsAsNullPanesToolStripMenuItem.Click += new System.EventHandler(this.viewPartsAsNullPanesToolStripMenuItem_Click);
this.panesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.transformChildrenToolStripMenuItem});
this.panesToolStripMenuItem.Name = "panesToolStripMenuItem";
this.panesToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.panesToolStripMenuItem.Text = "Panes";
//
// transformChildrenToolStripMenuItem
//
this.transformChildrenToolStripMenuItem.CheckOnClick = true;
this.transformChildrenToolStripMenuItem.Name = "transformChildrenToolStripMenuItem";
this.transformChildrenToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.transformChildrenToolStripMenuItem.Text = "Transform Children";
this.transformChildrenToolStripMenuItem.Click += new System.EventHandler(this.transformChildrenToolStripMenuItem_Click);
//
// LayoutEditor
//
@ -449,5 +470,7 @@
private System.Windows.Forms.ToolStripMenuItem undoToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem redoToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem viewPartsAsNullPanesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem panesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem transformChildrenToolStripMenuItem;
}
}

View file

@ -77,6 +77,7 @@ namespace LayoutBXLYT
renderInGamePreviewToolStripMenuItem.Checked = Runtime.LayoutEditor.IsGamePreview;
displayGridToolStripMenuItem.Checked = Runtime.LayoutEditor.DisplayGrid;
displayTextPanesToolStripMenuItem.Checked = Runtime.LayoutEditor.DisplayTextPane;
transformChildrenToolStripMenuItem.Checked = Runtime.LayoutEditor.TransformChidlren;
ObjectSelected += OnObjectSelected;
ObjectChanged += OnObjectChanged;
@ -244,6 +245,7 @@ namespace LayoutBXLYT
ActiveViewport.UpdateViewport();
}
private bool isSelectedInViewer = false;
private bool isChecked = false;
private void OnObjectSelected(object sender, EventArgs e)
{
@ -269,11 +271,12 @@ namespace LayoutBXLYT
}
if (LayoutPaneEditor != null && (string)sender == "Select")
{
ActiveViewport?.SelectedPanes.Clear();
if (e is TreeViewEventArgs) {
var node = ((TreeViewEventArgs)e).Node;
if (!isSelectedInViewer)
ActiveViewport?.SelectedPanes.Clear();
if (node.Tag is BasePane)
LoadPaneEditorOnSelect(node.Tag as BasePane);
else if (node.Tag is BxlytMaterial)
@ -321,7 +324,11 @@ namespace LayoutBXLYT
LayoutPaneEditor.Text = $"Properties [{pane.Name}] | (Null Pane)";
LayoutPaneEditor.LoadPane(pane, this);
ActiveViewport?.SelectedPanes.Add(pane);
if (ActiveViewport == null) return;
if (!ActiveViewport.SelectedPanes.Contains(pane))
ActiveViewport.SelectedPanes.Add(pane);
}
public void RefreshEditors()
@ -334,7 +341,9 @@ namespace LayoutBXLYT
var nodeWrapper = pane.NodeWrapper;
if (nodeWrapper == null) return;
isSelectedInViewer = true;
LayoutHierarchy?.SelectNode(nodeWrapper);
isSelectedInViewer = false;
}
private void UpdateAnimationNode(ListViewItem node)
@ -1080,5 +1089,9 @@ namespace LayoutBXLYT
}
#endregion
private void transformChildrenToolStripMenuItem_Click(object sender, EventArgs e) {
Runtime.LayoutEditor.TransformChidlren = transformChildrenToolStripMenuItem.Checked;
}
}
}

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Syroot.Maths;
using Toolbox.Library;
namespace LayoutBXLYT
{
@ -177,6 +178,47 @@ namespace LayoutBXLYT
}
public class UndoActionTransform : IRevertAction
{
bool TransformChidlren = false;
public List<PaneInfo> Panes = new List<PaneInfo>();
public UndoActionTransform(List<BasePane> panes)
{
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,
});
}
}
public IRevertAction Revert()
{
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;
}
return this;
}
public class PaneInfo
{
public Vector3F Translate;
public Vector3F Rotate;
@ -186,26 +228,6 @@ namespace LayoutBXLYT
public float Height;
public BasePane targetPane;
public UndoActionTransform(BasePane pane)
{
targetPane = pane;
Translate = pane.Translate;
Scale = pane.Scale;
Rotate = pane.Rotate;
Width = pane.Width;
Height = pane.Height;
}
public IRevertAction Revert()
{
targetPane.Translate = Translate;
targetPane.Scale = Scale;
targetPane.Rotate = Rotate;
targetPane.Width = Width;
targetPane.Height = Height;
return this;
}
}
}

View file

@ -238,7 +238,7 @@ namespace LayoutBXLYT
{
foreach (var pane in file.PaneLookup.Values)
{
if (!pane.Visible || !pane.DisplayInEditor)
if (!pane.Visible || !pane.DisplayInEditor && !pane.IsRoot)
continue;
//Hitbox debug
@ -306,9 +306,7 @@ namespace LayoutBXLYT
//Create a bounding box for all selected panes
//This box will allow resizing of all selected panes
if (SelectedPanes.Count > 0)
{
}
DrawSelectionBox(SelectedPanes, true);
if (UseOrtho)
GL.PopMatrix();
@ -318,9 +316,91 @@ namespace LayoutBXLYT
glControl1.SwapBuffers();
}
private void DrawRectangle()
private static CustomRectangle GetSelectedPanesBounding(List<BasePane> panes)
{
CustomRectangle rect = new CustomRectangle(0, 0, 0, 0);
List<Vector2> points = new List<Vector2>();
foreach (var pane in panes)
{
var paneRect = pane.CreateRectangle();
rect = paneRect.GetTransformedRectangle(pane.Parent, pane.Translate, pane.Rotate, pane.Scale);
points.AddRange(new Vector2[4]
{
new Vector2(rect.LeftPoint, rect.TopPoint),
new Vector2(rect.RightPoint, rect.TopPoint),
new Vector2(rect.RightPoint, rect.BottomPoint),
new Vector2(rect.LeftPoint, rect.BottomPoint)
});
var minX = (int)points.Min(p => p.X);
var maxX = (int)points.Max(p => p.X);
var minY = (int)points.Min(p => p.Y);
var maxY = (int)points.Max(p => p.Y);
rect = new CustomRectangle(minX, maxX, maxY, minY);
}
points.Clear();
return rect;
}
public static void DrawSelectionBox(List<BasePane> panes, bool isSelected)
{
//Create a rectangle with the largest points selected
CustomRectangle rect = GetSelectedPanesBounding(panes);
GL.Disable(EnableCap.Blend);
GL.Disable(EnableCap.AlphaTest);
GL.Disable(EnableCap.Texture2D);
GL.UseProgram(0);
GL.Begin(PrimitiveType.LineLoop);
GL.Color4(isSelected ? Color.Red : Color.Green);
GL.Vertex2(rect.LeftPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.BottomPoint);
GL.Vertex2(rect.RightPoint, rect.TopPoint);
GL.Vertex2(rect.LeftPoint, rect.TopPoint);
GL.End();
if (isSelected)
{
var transformed = rect;
var leftTop = new Vector2(transformed.LeftPoint, transformed.TopPoint);
var left = new Vector2(transformed.LeftPoint, (transformed.BottomPoint + transformed.TopPoint) / 2);
var leftBottom = new Vector2(transformed.LeftPoint, transformed.BottomPoint);
var rightTop = new Vector2(transformed.RightPoint, transformed.TopPoint);
var right = new Vector2(transformed.RightPoint, (transformed.BottomPoint + transformed.TopPoint) / 2);
var rightBottom = new Vector2(transformed.RightPoint, transformed.BottomPoint);
var top = new Vector2((transformed.RightPoint + transformed.LeftPoint) / 2, transformed.TopPoint);
var bottom = new Vector2((transformed.RightPoint + transformed.LeftPoint) / 2, transformed.BottomPoint);
DrawEdgeSquare(leftTop);
DrawEdgeSquare(left);
DrawEdgeSquare(leftBottom);
DrawEdgeSquare(rightTop);
DrawEdgeSquare(right);
DrawEdgeSquare(rightBottom);
DrawEdgeSquare(top);
DrawEdgeSquare(bottom);
}
GL.Enable(EnableCap.Blend);
GL.Enable(EnableCap.AlphaTest);
GL.Enable(EnableCap.Texture2D);
}
private static void DrawEdgeSquare(Vector2 position)
{
float scale = 5;
GL.Begin(PrimitiveType.LineLoop);
GL.Color4(Color.Red);
GL.Vertex2(position.X + -1 * scale, position.Y + -1 * scale);
GL.Vertex2(position.X + 1 * scale, position.Y + -1 * scale);
GL.Vertex2(position.X + 1 * scale, position.Y + 1 * scale);
GL.Vertex2(position.X + -1 * scale, position.Y + 1 * scale);
GL.End();
}
private void RenderPanes(BxlytShader shader, BasePane pane, bool isRoot, byte parentAlpha, bool parentAlphaInfluence, BasePane partPane = null, int stage = 0)
@ -516,7 +596,7 @@ namespace LayoutBXLYT
if (partPane != null)
RenderPanes(shader,partPane, true, effectiveAlpha, parentInfluenceAlpha);
else
DrawDefaultPane(shader, pane);
DrawDefaultPane(shader, pane, isSelected);
if (pane.Properties != null)
{
@ -688,26 +768,28 @@ namespace LayoutBXLYT
mouseDown = true;
RenderEditor();
var coords = convertScreenToWorldCoords(e.Location.X, e.Location.Y);
var coords = OpenGLHelper.convertScreenToWorldCoords(e.Location.X, e.Location.Y);
GL.PopMatrix();
bool hasEdgeHit = false;
foreach (var pane in SelectedPanes)
{
var edgePick = SearchEdgePicking(pane, coords.X, coords.Y);
var rect = GetSelectedPanesBounding(SelectedPanes);
var edgePick = SearchEdgePicking(rect, coords.X, coords.Y);
if (edgePick != PickAction.None)
{
pickAction = edgePick;
isPicked = true;
hasEdgeHit = true;
}
UndoManger.AddToUndo(new LayoutUndoManager.UndoActionTransform(pane));
if (hasEdgeHit)
{
UndoManger.AddToUndo(new LayoutUndoManager.UndoActionTransform(SelectedPanes));
pickOriginMouse = e.Location;
RenderScene();
return;
}
}
BasePane hitPane = null;
SearchHit(LayoutFile.RootPane, coords.X, coords.Y, ref hitPane);
@ -716,38 +798,36 @@ namespace LayoutBXLYT
pickAction = PickAction.Translate;
if (!SelectedPanes.Contains(hitPane))
{
if (Control.ModifierKeys != Keys.Control)
SelectedPanes.Clear();
SelectedPanes.Add(hitPane);
foreach (var pane in SelectedPanes)
{
var edgePick = SearchEdgePicking(pane, coords.X, coords.Y);
if (edgePick != PickAction.None)
pickAction = edgePick;
Console.WriteLine(pane.Name + " " + pickAction);
}
foreach (var pane in SelectedPanes)
{
UndoManger.AddToUndo(new LayoutUndoManager.UndoActionTransform(pane));
}
var paneRect = GetSelectedPanesBounding(SelectedPanes);
var paneEdgePick = SearchEdgePicking(paneRect, coords.X, coords.Y);
if (paneEdgePick != PickAction.None)
pickAction = paneEdgePick;
UndoManger.AddToUndo(new LayoutUndoManager.UndoActionTransform(SelectedPanes));
ParentEditor.UpdateUndo();
ParentEditor.UpdateHiearchyNodeSelection(hitPane);
isPicked = true;
} //Check edge hit and control key (multi selecting panes)
else if (!hasEdgeHit && Control.ModifierKeys != Keys.Control)
} //Check control key (multi selecting panes)
else if (Control.ModifierKeys != Keys.Control)
SelectedPanes.Clear();
pickOriginMouse = e.Location;
RenderScene();
pickOriginMouse = e.Location;
}
else if (e.Button == MouseButtons.Right)
{
RenderEditor();
var coords = convertScreenToWorldCoords(e.Location.X, e.Location.Y);
var coords = OpenGLHelper.convertScreenToWorldCoords(e.Location.X, e.Location.Y);
pickOriginMouse = coords;
GL.PopMatrix();
@ -963,9 +1043,8 @@ namespace LayoutBXLYT
return SelectedPanes;
}
private PickAction SearchEdgePicking(BasePane pane, int X, int Y)
private PickAction SearchEdgePicking(CustomRectangle transformed, int X, int Y)
{
var transformed = pane.CreateRectangle().GetTransformedRectangle(pane.Parent, pane.Translate, pane.Rotate, pane.Scale);
var leftTop = new Point(transformed.LeftPoint, transformed.TopPoint);
var left = new Point(transformed.LeftPoint, (transformed.BottomPoint + transformed.TopPoint) / 2);
var leftBottom = new Point(transformed.LeftPoint, transformed.BottomPoint);
@ -1053,15 +1132,16 @@ namespace LayoutBXLYT
if (SelectedPanes.Count > 0 && !showSelectionBox)
{
RenderEditor();
var posWorld = convertScreenToWorldCoords(e.Location.X, e.Location.Y);
var posWorld = OpenGLHelper.convertScreenToWorldCoords(e.Location.X, e.Location.Y);
GL.PopMatrix();
//Setup edge picking with move event
bool hasPick = false;
foreach (var pane in SelectedPanes)
{
var pickState = SearchEdgePicking(pane, posWorld.X, posWorld.Y);
var paneRect = GetSelectedPanesBounding(SelectedPanes);
var pickState = SearchEdgePicking(paneRect, posWorld.X, posWorld.Y);
if (pickState != PickAction.None)
{
if (pickState == PickAction.DragTop)
@ -1094,7 +1174,6 @@ namespace LayoutBXLYT
hasPick = true;
}
}
if (!hasPick)
Cursor.Current = Cursors.Default;
@ -1104,8 +1183,8 @@ namespace LayoutBXLYT
{
RenderEditor();
var temp = e.Location;
var curPos = convertScreenToWorldCoords(temp.X, temp.Y);
var prevPos = convertScreenToWorldCoords(pickOriginMouse.X, pickOriginMouse.Y);
var curPos = OpenGLHelper.convertScreenToWorldCoords(temp.X, temp.Y);
var prevPos = OpenGLHelper.convertScreenToWorldCoords(pickOriginMouse.X, pickOriginMouse.Y);
var pickMouse = new Point((int)(prevPos.X - curPos.X), (int)(prevPos.Y - curPos.Y));
if (pickAction == PickAction.Translate)
@ -1128,6 +1207,9 @@ namespace LayoutBXLYT
posY = pane.Translate.Y - pickMouse.Y;
}
if (!Runtime.LayoutEditor.TransformChidlren)
pane.KeepChildrenTransform(posX, posY);
if (snapToGrid)
{
int gridCubeWidth = 16, gridCubeHeight = 16;
@ -1146,9 +1228,11 @@ namespace LayoutBXLYT
}
else if (!showSelectionBox)
{
var selectionBox = GetSelectedPanesBounding(SelectedPanes);
//Setup edge picking with move event
foreach (var pane in SelectedPanes)
pane.TransformRectangle(pickAction, pickMouse.X, pickMouse.Y);
pane.TransformRectangle(pickAction, selectionBox, pickMouse.X, pickMouse.Y);
}
pickOriginMouse = temp;
@ -1160,8 +1244,8 @@ namespace LayoutBXLYT
{
RenderEditor();
var temp = e.Location;
var curPos = convertScreenToWorldCoords(temp.X, temp.Y);
var prevPos = convertScreenToWorldCoords(pickOriginMouse.X, pickOriginMouse.Y);
var curPos = OpenGLHelper.convertScreenToWorldCoords(temp.X, temp.Y);
var prevPos = OpenGLHelper.convertScreenToWorldCoords(pickOriginMouse.X, pickOriginMouse.Y);
DrawSelectionBox(prevPos, curPos);
}
@ -1209,45 +1293,6 @@ namespace LayoutBXLYT
RenderScene(true);
}
public static Point convertScreenToWorldCoords(int x, int y)
{
int[] viewport = new int[4];
Matrix4 modelViewMatrix, projectionMatrix;
GL.GetFloat(GetPName.ModelviewMatrix, out modelViewMatrix);
GL.GetFloat(GetPName.ProjectionMatrix, out projectionMatrix);
GL.GetInteger(GetPName.Viewport, viewport);
Vector2 mouse;
mouse.X = x;
mouse.Y = y;
Vector4 vector = UnProject(ref projectionMatrix, modelViewMatrix, new Size(viewport[2], viewport[3]), mouse);
Point coords = new Point((int)vector.X, (int)vector.Y);
return coords;
}
public static Vector4 UnProject(ref Matrix4 projection, Matrix4 view, Size viewport, Vector2 mouse)
{
Vector4 vec;
vec.X = (2.0f * mouse.X / (float)viewport.Width - 1);
vec.Y = -(2.0f * mouse.Y / (float)viewport.Height - 1);
vec.Z = 0;
vec.W = 1.0f;
Matrix4 viewInv = Matrix4.Invert(view);
Matrix4 projInv = Matrix4.Invert(projection);
Vector4.Transform(ref vec, ref projInv, out vec);
Vector4.Transform(ref vec, ref viewInv, out vec);
if (vec.W > float.Epsilon || vec.W < float.Epsilon)
{
vec.X /= vec.W;
vec.Y /= vec.W;
vec.Z /= vec.W;
}
return vec;
}
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
@ -1321,7 +1366,7 @@ namespace LayoutBXLYT
var point = this.PointToClient(new Point(e.X, e.Y));
RenderEditor();
var coords = convertScreenToWorldCoords(point.X, point.Y);
var coords = OpenGLHelper.convertScreenToWorldCoords(point.X, point.Y);
GL.PopMatrix();
var pane = ParentEditor.AddNewPicturePane();

View file

@ -288,6 +288,9 @@ namespace Toolbox.Library
case "PartsAsNullPanes":
bool.TryParse(node.InnerText, out Runtime.LayoutEditor.PartsAsNullPanes);
break;
case "TransformPaneChidlren":
bool.TryParse(node.InnerText, out Runtime.LayoutEditor.TransformChidlren);
break;
}
}
@ -415,6 +418,7 @@ namespace Toolbox.Library
layoutSettingsNode.AppendChild(createNode(doc, "DisplayWindowPane", Runtime.LayoutEditor.DisplayWindowPane.ToString()));
layoutSettingsNode.AppendChild(createNode(doc, "DisplayTextPane", Runtime.LayoutEditor.DisplayTextPane.ToString()));
layoutSettingsNode.AppendChild(createNode(doc, "PartsAsNullPanes", Runtime.LayoutEditor.PartsAsNullPanes.ToString()));
layoutSettingsNode.AppendChild(createNode(doc, "TransformPaneChidlren", Runtime.LayoutEditor.TransformChidlren.ToString()));
}
private static void AppendDeveloperSettings(XmlDocument doc, XmlNode parentNode)

View file

@ -64,6 +64,8 @@ namespace Toolbox.Library
public class LayoutEditor
{
public static bool TransformChidlren = false;
public static bool PartsAsNullPanes = false;
public static bool IsGamePreview = false;
public static bool DisplayNullPane = true;