Files
project-reset/Assets/Plugins/LiveWatchLite/Scripts/Editor/Utilities/RectExtensions.cs
2025-08-31 18:14:07 -04:00

307 lines
9.3 KiB
C#

using System;
using UnityEngine;
namespace Ingvar.LiveWatch.Editor
{
public enum CropEdge
{
LeftLocal = 1,
RightLocal = 2,
TopLocal = 3,
BottomLocal = 4,
HorizontalGlobal = 5,
VerticalGlobal = 6
}
public enum WidthSetSpace
{
Left = 0,
Center = 1,
Right = 2
}
public enum HeightSetSpace
{
Top = 0,
Center = 1,
Bottom = 2
}
[Flags]
public enum ExtrudeFlags
{
Left = 1 << 1,
Right = 1 << 2,
Top = 1 << 3,
Bottom = 1 << 4,
None = 0,
All = ~None
}
public static class RectExtensions
{
#region Offset
public static Rect Offset(this Rect rect, float xDelta, float yDelta, float widthDelta, float heightDelta)
{
return new Rect(rect.x + xDelta, rect.y + yDelta, rect.width + widthDelta, rect.height + heightDelta);
}
public static Rect OffsetByX(this Rect rect, float xDelta)
{
return new Rect(rect.x + xDelta, rect.y, rect.width, rect.height);
}
public static Rect OffsetByY(this Rect rect, float yDelta)
{
return new Rect(rect.x, rect.y + yDelta, rect.width, rect.height);
}
public static Rect OffsetByWidth(this Rect rect, float widthDelta)
{
return new Rect(rect.x, rect.y, rect.width + widthDelta, rect.height);
}
public static Rect OffsetByHeight(this Rect rect, float heightDelta)
{
return new Rect(rect.x, rect.y, rect.width, rect.height + heightDelta);
}
#endregion
#region Extrude
public static Rect Extrude(this Rect rect, ExtrudeFlags flags, float size)
{
var xMin = rect.xMin;
var xMax = rect.xMax;
var yMin = rect.yMin;
var yMax = rect.yMax;
if ((flags & ExtrudeFlags.Left) == ExtrudeFlags.Left)
xMin -= size;
if ((flags & ExtrudeFlags.Right) == ExtrudeFlags.Right)
xMax += size;
if ((flags & ExtrudeFlags.Top) == ExtrudeFlags.Top)
yMin -= size;
if ((flags & ExtrudeFlags.Bottom) == ExtrudeFlags.Bottom)
yMax += size;
return Rect.MinMaxRect(xMin, yMin, xMax, yMax);
}
#endregion
#region Set
public static Rect SetX(this Rect rect, float x)
{
return new Rect(x, rect.y, rect.width, rect.height);
}
public static Rect SetY(this Rect rect, float y)
{
return new Rect(rect.x, y, rect.width, rect.height);
}
public static Rect SetWidth(this Rect rect, float width, WidthSetSpace setSpace = WidthSetSpace.Left)
{
switch (setSpace)
{
case WidthSetSpace.Left:
return new Rect(rect.x, rect.y, width, rect.height);
case WidthSetSpace.Center:
return new Rect(rect.center.x - width/2, rect.y, width, rect.height);
case WidthSetSpace.Right:
return new Rect(rect.xMax - width, rect.y, width, rect.height);
default:
throw new ArgumentOutOfRangeException(nameof(setSpace), setSpace, null);
}
}
public static Rect SetHeight(this Rect rect, float height, HeightSetSpace setSpace = HeightSetSpace.Top)
{
switch (setSpace)
{
case HeightSetSpace.Top:
return new Rect(rect.x, rect.y, rect.width, height);
case HeightSetSpace.Center:
return new Rect(rect.x, rect.center.y - height / 2, rect.width, height);
case HeightSetSpace.Bottom:
return new Rect(rect.x, rect.yMax - height, rect.width, height);
default:
throw new ArgumentOutOfRangeException(nameof(setSpace), setSpace, null);
}
}
#endregion
#region TakeEdge
public static Rect CropFromStartToPosition(this Rect rect, CropEdge crop, float position)
{
switch (crop)
{
case CropEdge.LeftLocal:
return new Rect(rect.x, rect.y, position, rect.height);
case CropEdge.RightLocal:
return new Rect(rect.xMax - position, rect.y, position, rect.height);
case CropEdge.TopLocal:
return new Rect(rect.x, rect.y, rect.width, position);
case CropEdge.BottomLocal:
return new Rect(rect.x, rect.yMax - position, rect.width, position);
case CropEdge.HorizontalGlobal:
return new Rect(rect.x, rect.y, position - rect.x, rect.height);
case CropEdge.VerticalGlobal:
return new Rect(rect.x, rect.y, rect.width, position - rect.y);
default:
throw new ArgumentOutOfRangeException(nameof(crop), crop, null);
}
}
public static Rect CropFromPositionToEnd(this Rect rect, CropEdge crop, float position)
{
switch (crop)
{
case CropEdge.LeftLocal:
return new Rect(rect.x + position, rect.y, rect.width - position, rect.height);
case CropEdge.RightLocal:
return new Rect(rect.x, rect.y, rect.width - position, rect.height);
case CropEdge.TopLocal:
return new Rect(rect.x, rect.y + position, rect.width, rect.height - position);
case CropEdge.BottomLocal:
return new Rect(rect.x, rect.y, rect.width, rect.height - position);
case CropEdge.HorizontalGlobal:
return new Rect(position, rect.y, rect.xMax - position, rect.height);
case CropEdge.VerticalGlobal:
return new Rect(rect.x, position, rect.width, rect.yMax - position);
default:
throw new ArgumentOutOfRangeException(nameof(crop), crop, null);
}
}
public static Rect CropFromPositionWithSize(this Rect rect, CropEdge crop, float position, float size)
{
switch (crop)
{
case CropEdge.LeftLocal:
return new Rect(rect.x + position, rect.y, size, rect.height);
case CropEdge.RightLocal:
return new Rect(rect.xMax - position - size, rect.y, size, rect.height);
case CropEdge.TopLocal:
return new Rect(rect.x, rect.y + position, rect.width, size);
case CropEdge.BottomLocal:
return new Rect(rect.x, rect.yMax - position - size, rect.width, size);
case CropEdge.HorizontalGlobal:
return new Rect(position, rect.y, size, rect.height);
case CropEdge.VerticalGlobal:
return new Rect(rect.x, position, rect.width, size);
default:
throw new ArgumentOutOfRangeException(nameof(crop), crop, null);
}
}
public static Rect CropFromPositionToPosition(this Rect rect, CropEdge crop, float positionStart, float positionEnd)
{
switch (crop)
{
case CropEdge.LeftLocal:
return new Rect(rect.x + positionStart, rect.y, positionEnd - positionStart, rect.height);
case CropEdge.RightLocal:
return new Rect(rect.xMax - positionEnd, rect.y, positionEnd - positionStart, rect.height);
case CropEdge.TopLocal:
return new Rect(rect.x, rect.y + positionStart, rect.width, positionEnd - positionStart);
case CropEdge.BottomLocal:
return new Rect(rect.x, rect.yMax - positionEnd, rect.width, positionEnd - positionStart);
case CropEdge.HorizontalGlobal:
return new Rect(positionStart, rect.y, positionEnd - positionStart, rect.height);
case CropEdge.VerticalGlobal:
return new Rect(rect.x, positionStart, rect.width, positionEnd - positionStart);
default:
throw new ArgumentOutOfRangeException(nameof(crop), crop, null);
}
}
#endregion
#region Clamp
public static float ClampPositionX(this Rect rect, float xPosition)
{
return Mathf.Clamp(xPosition, rect.xMin, rect.xMax);
}
public static float ClampPositionY(this Rect rect, float yPosition)
{
return Mathf.Clamp(yPosition, rect.yMin, rect.yMax);
}
public static Vector2 ClampPosition(this Rect rect, Vector2 position)
{
return new Vector2(rect.ClampPositionX(position.x), rect.ClampPositionY(position.y));
}
#endregion
public static Rect FitInRect(this Rect rect, Rect rectToFitIn)
{
return Rect.MinMaxRect(
Mathf.Max(rect.xMin, rectToFitIn.xMin),
Mathf.Max(rect.yMin, rectToFitIn.yMin),
Mathf.Min(rect.xMax, rectToFitIn.xMax),
Mathf.Min(rect.yMax, rectToFitIn.yMax));
}
public static Rect RelativeToOther(this Rect rect, Rect otherRect)
{
return new Rect(
rect.x - otherRect.x,
rect.y - otherRect.y,
rect.width,
rect.height);
}
public static RectInt ToRectInt(this Rect rect)
{
return new RectInt(
Mathf.RoundToInt(rect.x),
Mathf.RoundToInt(rect.y),
Mathf.RoundToInt(rect.width),
Mathf.RoundToInt(rect.height));
}
}
}