I need something to diff against
This commit is contained in:
@@ -13,15 +13,204 @@ namespace FlaxEditor.Surface
|
||||
[HideInEditor]
|
||||
public class ResizableSurfaceNode : SurfaceNode
|
||||
{
|
||||
private Float2 _resizeWeight;
|
||||
private Float2 _startResizingSize;
|
||||
private Float2 _surfaceMouseLocation;
|
||||
private bool _isMouseOverResizeBorder;
|
||||
private class ResizeBorder : Control
|
||||
{
|
||||
private const float BorderWidth = 15f;
|
||||
private const float ResizeOnAxisThreshold = 0.85f;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the node is currently being resized.
|
||||
/// </summary>
|
||||
protected bool _isResizing;
|
||||
public VisjectSurface Surface;
|
||||
public ResizableSurfaceNode ResizeableNode;
|
||||
|
||||
private Float2 _surfaceMouseLocation;
|
||||
private Float2 startResizingSize;
|
||||
|
||||
public bool IsMouseOverResizeBorder { get; private set; }
|
||||
public bool IsResizing { get; private set; }
|
||||
|
||||
public Action StartResize;
|
||||
public Action EndResize;
|
||||
|
||||
public Float2 ResizeWeight { get; private set; }
|
||||
public CursorType CursorType
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((ResizeWeight.X == 1 && ResizeWeight.Y == 0) || (ResizeWeight.X == -1 && ResizeWeight.Y == 0))
|
||||
return CursorType.SizeWE;
|
||||
if ((ResizeWeight.X == 0 && ResizeWeight.Y == 1) || (ResizeWeight.X == 0 && ResizeWeight.Y == -1))
|
||||
return CursorType.SizeNS;
|
||||
if ((ResizeWeight.X == -1 && ResizeWeight.Y == -1) || (ResizeWeight.X == 1 && ResizeWeight.Y == 1))
|
||||
return CursorType.SizeNWSE;
|
||||
if ((ResizeWeight.X == 1 && ResizeWeight.Y == -1) || (ResizeWeight.X == -1 && ResizeWeight.Y == 1))
|
||||
return CursorType.SizeNESW;
|
||||
|
||||
return CursorType.Default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ResizeBorder(VisjectSurface surface, ResizableSurfaceNode resizeableNode)
|
||||
{
|
||||
Surface = surface;
|
||||
ResizeableNode = resizeableNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates location and size to match the resizeable node with the additional padding.
|
||||
/// </summary>
|
||||
/// <param name="nodeSize">The node size.</param>
|
||||
/// <param name="nodeLocation">The node location.</param>
|
||||
public void MatchResizeableNode(Float2 nodeSize, Float2 nodeLocation)
|
||||
{
|
||||
Size = nodeSize + new Float2(BorderWidth);
|
||||
Location = nodeLocation - new Float2(BorderWidth * 0.5f);
|
||||
}
|
||||
|
||||
private void UpdateSurfaceMouseLocation()
|
||||
{
|
||||
_surfaceMouseLocation = Surface.PointFromScreen(Input.MouseScreenPosition);
|
||||
}
|
||||
|
||||
private void UpdateResizeFlags(Float2 location)
|
||||
{
|
||||
var borderRect = Bounds with { Location = Float2.Zero };
|
||||
bool onBorder = borderRect.Contains(location);
|
||||
|
||||
Float2 rawResizeWeight = (location - borderRect.Center) / (borderRect.Size * 0.5f);
|
||||
ResizeWeight = new Float2(Mathf.Abs(rawResizeWeight.X) >= ResizeOnAxisThreshold ? Mathf.Sign(rawResizeWeight.X) : 0,
|
||||
Mathf.Abs(rawResizeWeight.Y) >= ResizeOnAxisThreshold ? Mathf.Sign(rawResizeWeight.Y) : 0);
|
||||
|
||||
IsMouseOverResizeBorder = onBorder && !ResizeableNode.IsMouseOver;
|
||||
}
|
||||
|
||||
private Float2 GetControlDelta(Control control, ref Float2 start, ref Float2 end)
|
||||
{
|
||||
var pointOrigin = control.Parent ?? control;
|
||||
var startPos = pointOrigin.PointFromParent(ResizeableNode, start);
|
||||
var endPos = pointOrigin.PointFromParent(ResizeableNode, end);
|
||||
return endPos - startPos;
|
||||
}
|
||||
|
||||
private void EndResizing()
|
||||
{
|
||||
EndMouseCapture();
|
||||
IsResizing = false;
|
||||
if (startResizingSize != ResizeableNode.Size)
|
||||
{
|
||||
var emptySize = ResizeableNode.CalculateNodeSize(0, 0);
|
||||
ResizeableNode.SizeValue = ResizeableNode.Size - emptySize;
|
||||
Surface.MarkAsEdited(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMouseLeave()
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
IsMouseOverResizeBorder = false;
|
||||
base.OnMouseLeave();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
if (!IsResizing)
|
||||
{
|
||||
UpdateResizeFlags(location);
|
||||
}
|
||||
else
|
||||
{
|
||||
var resizeAxisAbs = ResizeWeight.Absolute;
|
||||
var resizeAxisPos = Float2.Clamp(ResizeWeight, Float2.Zero, Float2.One);
|
||||
var resizeAxisNeg = Float2.Clamp(-ResizeWeight, Float2.Zero, Float2.One);
|
||||
|
||||
var currentSurfaceMouse = Surface.PointFromScreen(Input.MouseScreenPosition);
|
||||
var delta = currentSurfaceMouse - _surfaceMouseLocation;
|
||||
// TODO: scale/size snapping?
|
||||
delta *= resizeAxisAbs;
|
||||
|
||||
var moveLocation = _surfaceMouseLocation + delta;
|
||||
|
||||
// TODO: Do I need GetControlDelta?
|
||||
var uiControlDelta = GetControlDelta(this, ref _surfaceMouseLocation, ref moveLocation);
|
||||
var emptySize = ResizeableNode.CalculateNodeSize(0, 0);
|
||||
ResizeableNode.Size += uiControlDelta * resizeAxisPos - uiControlDelta * resizeAxisNeg;
|
||||
Float2 oldSize = ResizeableNode.Size;
|
||||
ResizeableNode.Size = new Float2(Mathf.Max(ResizeableNode.Size.X, ResizeableNode.sizeMin.X), Mathf.Max(ResizeableNode.Size.Y, ResizeableNode.sizeMin.Y));
|
||||
if (oldSize == ResizeableNode.Size) // Only move if size wasn't clamped
|
||||
{
|
||||
ResizeableNode.Location += uiControlDelta * resizeAxisNeg;
|
||||
}
|
||||
ResizeableNode.SizeValue = ResizeableNode.Size - emptySize;
|
||||
ResizeableNode.SizeValue = new Float2(Mathf.Max(ResizeableNode.SizeValue.X, ResizeableNode.sizeMin.X), Mathf.Max(ResizeableNode.SizeValue.Y, ResizeableNode.sizeMin.Y));
|
||||
ResizeableNode.CalculateNodeSize(ResizeableNode.Size.X, ResizeableNode.Size.Y);
|
||||
UpdateSurfaceMouseLocation();
|
||||
MatchResizeableNode(ResizeableNode.Size, ResizeableNode.Location);
|
||||
}
|
||||
|
||||
if (IsMouseOverResizeBorder)
|
||||
Cursor = CursorType;
|
||||
else
|
||||
Cursor = CursorType.Default;
|
||||
|
||||
|
||||
|
||||
base.OnMouseMove(location);
|
||||
}
|
||||
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && IsMouseOverResizeBorder && !IsResizing)
|
||||
{
|
||||
// Start resizing
|
||||
UpdateSurfaceMouseLocation();
|
||||
IsResizing = true;
|
||||
startResizingSize = ResizeableNode.Size;
|
||||
StartMouseCapture();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && IsResizing)
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
EndResizing();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseUp(location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnLostFocus()
|
||||
{
|
||||
if (IsResizing)
|
||||
EndResizing();
|
||||
|
||||
base.OnLostFocus();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnEndMouseCapture()
|
||||
{
|
||||
if (IsResizing)
|
||||
EndResizing();
|
||||
|
||||
base.OnEndMouseCapture();
|
||||
}
|
||||
|
||||
//public override void Draw()
|
||||
//{
|
||||
// Render2D.DrawRectangle(new Rectangle(Float2.Zero, Size), Color.Blue, 1f);
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
private ResizeBorder resizeBorder;
|
||||
|
||||
/// <summary>
|
||||
/// Index of the Float2 value in the node values list to store node size.
|
||||
@@ -31,7 +220,7 @@ namespace FlaxEditor.Surface
|
||||
/// <summary>
|
||||
/// Minimum node size.
|
||||
/// </summary>
|
||||
protected Float2 _sizeMin = new Float2(240, 160);
|
||||
protected Float2 sizeMin = new Float2(240, 160);
|
||||
|
||||
private Float2 SizeValue
|
||||
{
|
||||
@@ -43,12 +232,27 @@ namespace FlaxEditor.Surface
|
||||
public ResizableSurfaceNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
|
||||
: base(id, context, nodeArch, groupArch)
|
||||
{
|
||||
CullChildren = false;
|
||||
ClipChildren = false;
|
||||
resizeBorder = new ResizeBorder(Surface, this)
|
||||
{
|
||||
Parent = Surface.SurfaceRoot,
|
||||
};
|
||||
|
||||
resizeBorder.MatchResizeableNode(Size, Location);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnLocationChanged()
|
||||
{
|
||||
resizeBorder.MatchResizeableNode(Size, Location);
|
||||
base.OnLocationChanged();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanSelect(ref Float2 location)
|
||||
{
|
||||
return base.CanSelect(ref location);// && !_resizeButtonRect.MakeOffsetted(Location).Contains(ref location);
|
||||
return base.CanSelect(ref location);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -59,6 +263,7 @@ namespace FlaxEditor.Surface
|
||||
if (Surface != null && Surface.GridSnappingEnabled)
|
||||
size = Surface.SnapToGrid(size, true);
|
||||
Resize(size.X, size.Y);
|
||||
resizeBorder.MatchResizeableNode(Size, Location);
|
||||
|
||||
base.OnSurfaceLoaded(action);
|
||||
}
|
||||
@@ -77,161 +282,10 @@ namespace FlaxEditor.Surface
|
||||
{
|
||||
base.Draw();
|
||||
|
||||
if (Surface.CanEdit && (_isResizing || _isMouseOverResizeBorder))
|
||||
if (Surface.CanEdit && (resizeBorder.IsResizing || resizeBorder.IsMouseOverResizeBorder))
|
||||
{
|
||||
Render2D.DrawRectangle(new Rectangle(Float2.Zero, Size), Style.Current.Foreground, 2f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnLostFocus()
|
||||
{
|
||||
if (_isResizing)
|
||||
EndResizing();
|
||||
|
||||
base.OnLostFocus();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnEndMouseCapture()
|
||||
{
|
||||
if (_isResizing)
|
||||
EndResizing();
|
||||
|
||||
base.OnEndMouseCapture();
|
||||
}
|
||||
|
||||
private bool UpdateIsOverResizeBorder(Float2 location)
|
||||
{
|
||||
const float ResizeBorderHalfWidth = 20f;
|
||||
const float ResizeOnAxisThreshold = 0.85f;
|
||||
|
||||
var nodeRect = new Rectangle(Float2.Zero, Size);
|
||||
bool onBorder = nodeRect.MakeExpanded(ResizeBorderHalfWidth).Contains(location);
|
||||
var inNodeRect = nodeRect.MakeExpanded(-ResizeBorderHalfWidth);
|
||||
bool inNode = inNodeRect.Contains(location);
|
||||
|
||||
Float2 rawResizeWeight = (location - nodeRect.Center) / (nodeRect.Size * 0.5f);
|
||||
_resizeWeight = new Float2(Mathf.Abs(rawResizeWeight.X) >= ResizeOnAxisThreshold ? Mathf.Sign(rawResizeWeight.X) : 0,
|
||||
Mathf.Abs(rawResizeWeight.Y) >= ResizeOnAxisThreshold ? Mathf.Sign(rawResizeWeight.Y) : 0);
|
||||
|
||||
_isMouseOverResizeBorder = onBorder && !inNode;
|
||||
return onBorder && !inNode;
|
||||
}
|
||||
|
||||
private CursorType ResizeWeightToCursorType()
|
||||
{
|
||||
if ((_resizeWeight.X == 1 && _resizeWeight.Y == 0) || (_resizeWeight.X == -1 && _resizeWeight.Y == 0))
|
||||
return CursorType.SizeWE;
|
||||
if ((_resizeWeight.X == 0 && _resizeWeight.Y == 1) || (_resizeWeight.X == 0 && _resizeWeight.Y == -1))
|
||||
return CursorType.SizeNS;
|
||||
if ((_resizeWeight.X == -1 && _resizeWeight.Y == -1) || (_resizeWeight.X == 1 && _resizeWeight.Y == 1))
|
||||
return CursorType.SizeNWSE;
|
||||
if ((_resizeWeight.X == 1 && _resizeWeight.Y == -1) || (_resizeWeight.X == -1 && _resizeWeight.Y == 1))
|
||||
return CursorType.SizeNESW;
|
||||
return CursorType.Default;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
if (base.OnMouseDown(location, button))
|
||||
return true;
|
||||
|
||||
if (button == MouseButton.Left && UpdateIsOverResizeBorder(location))
|
||||
{
|
||||
// Start resizing
|
||||
UpdateSurfaceMouseLocation();
|
||||
_isResizing = true;
|
||||
_startResizingSize = Size;
|
||||
StartMouseCapture();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Float2 GetControlDelta(Control control, ref Float2 start, ref Float2 end)
|
||||
{
|
||||
var pointOrigin = control.Parent ?? control;
|
||||
var startPos = pointOrigin.PointFromParent(this, start);
|
||||
var endPos = pointOrigin.PointFromParent(this, end);
|
||||
return endPos - startPos;
|
||||
}
|
||||
|
||||
private void UpdateSurfaceMouseLocation()
|
||||
{
|
||||
_surfaceMouseLocation = Surface.PointFromScreen(Input.MouseScreenPosition);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
if (_isResizing)
|
||||
{
|
||||
var resizeAxisAbs = _resizeWeight.Absolute;
|
||||
var resizeAxisPos = Float2.Clamp(_resizeWeight, Float2.Zero, Float2.One);
|
||||
var resizeAxisNeg = Float2.Clamp(-_resizeWeight, Float2.Zero, Float2.One);
|
||||
|
||||
var delta = PointToParent(Surface, location) - _surfaceMouseLocation;
|
||||
// TODO: scale/size snapping?
|
||||
delta *= resizeAxisAbs;
|
||||
|
||||
var moveLocation = _surfaceMouseLocation + delta;
|
||||
|
||||
// TODO: Do I need GetControlDelta?
|
||||
var uiControlDelta = GetControlDelta(this, ref _surfaceMouseLocation, ref moveLocation);
|
||||
var emptySize = CalculateNodeSize(0, 0);
|
||||
Location += uiControlDelta * resizeAxisNeg;
|
||||
Size += uiControlDelta * resizeAxisPos - uiControlDelta * resizeAxisNeg;
|
||||
Size = new Float2(Mathf.Max(Size.X, _sizeMin.X), Mathf.Max(Size.Y, _sizeMin.Y));
|
||||
SizeValue = Size - emptySize;
|
||||
SizeValue = new Float2(Mathf.Max(SizeValue.X, _sizeMin.X), Mathf.Max(SizeValue.Y, _sizeMin.Y));
|
||||
CalculateNodeSize(Size.X, Size.Y);
|
||||
UpdateSurfaceMouseLocation();
|
||||
}
|
||||
else if (UpdateIsOverResizeBorder(location))
|
||||
{
|
||||
Cursor = ResizeWeightToCursorType();
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
base.OnMouseMove(location);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseLeave()
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
_isMouseOverResizeBorder = false;
|
||||
base.OnMouseLeave();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && _isResizing)
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
EndResizing();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseUp(location, button);
|
||||
}
|
||||
|
||||
private void EndResizing()
|
||||
{
|
||||
EndMouseCapture();
|
||||
_isResizing = false;
|
||||
if (_startResizingSize != Size)
|
||||
{
|
||||
var emptySize = CalculateNodeSize(0, 0);
|
||||
SizeValue = Size - emptySize;
|
||||
Surface.MarkAsEdited(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace FlaxEditor.Surface
|
||||
: base(id, context, nodeArch, groupArch)
|
||||
{
|
||||
_sizeValueIndex = 2; // Index of the Size stored in Values array
|
||||
_sizeMin = new Float2(140.0f, Constants.NodeHeaderSize);
|
||||
sizeMin = new Float2(140.0f, Constants.NodeHeaderSize);
|
||||
_renameTextBox = new TextBox(false, 0, 0, Width)
|
||||
{
|
||||
Height = Constants.NodeHeaderSize,
|
||||
|
||||
Reference in New Issue
Block a user