Net.Like.Xue.Tokyo/Assets/Plugins/Le Tai's Asset/TranslucentImage/Script/Utilities/ResizableScreenRect.cs

168 lines
6.0 KiB
C#
Raw Normal View History

2024-11-03 16:42:23 +08:00
// Due to the use of asmdef in the ../Editor folder, this class cannot be put there,
// as then it cannot be referenced outside of the assembly
// The Blur region GUI requires the use of OnGUI for interactivity,
// so it cannot be completely done within the custom Editor either
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
namespace LeTai.Asset.TranslucentImage
{
public static class ResizableScreenRect
{
const float BORDER_THICKNESS = 2;
const float DRAG_EXTEND = 16;
delegate void DragHandlerDelegate(Vector2 delta, ref Rect rect);
static DragHandlerDelegate currentDragHandler;
static void DrawSquareFromCenter(Vector2 postion, float extent)
{
var v = Vector2.one * extent;
GUI.DrawTexture(new Rect(postion - v, v * 2), Texture2D.whiteTexture);
}
public static Rect Draw(Rect normalizedScreenRect)
{
var guiRect = normalizedScreenRect;
guiRect.y = 1 - guiRect.y - guiRect.height;
guiRect.x *= Screen.width;
guiRect.width *= Screen.width;
guiRect.y *= Screen.height;
guiRect.height *= Screen.height;
var borderThickness = BORDER_THICKNESS * EditorGUIUtility.pixelsPerPoint;
GUI.DrawTexture(new Rect(guiRect.x - borderThickness,
guiRect.y - borderThickness,
borderThickness,
guiRect.height + borderThickness * 2),
Texture2D.whiteTexture);
GUI.DrawTexture(new Rect(guiRect.x,
guiRect.y - borderThickness,
guiRect.width + 1,
borderThickness),
Texture2D.whiteTexture);
GUI.DrawTexture(new Rect(guiRect.xMax,
guiRect.y - borderThickness,
borderThickness,
guiRect.height + borderThickness * 2),
Texture2D.whiteTexture);
GUI.DrawTexture(new Rect(guiRect.x,
guiRect.yMax,
guiRect.width + 1,
borderThickness),
Texture2D.whiteTexture);
var boxExtend = borderThickness * 2;
DrawSquareFromCenter(guiRect.min, boxExtend);
DrawSquareFromCenter(guiRect.max, boxExtend);
DrawSquareFromCenter(new Vector2(guiRect.xMax, guiRect.yMin), boxExtend);
DrawSquareFromCenter(new Vector2(guiRect.xMin, guiRect.yMax), boxExtend);
return HandleEvent(guiRect);
}
static Rect HandleEvent(Rect guiRect)
{
if (Event.current.type == EventType.MouseDown)
{
currentDragHandler = ChooseDragHandler(guiRect, Event.current.mousePosition);
}
else if (Event.current.type == EventType.MouseUp)
{
currentDragHandler = null;
}
else if (Event.current.type == EventType.MouseDrag)
{
currentDragHandler?.Invoke(Event.current.delta, ref guiRect);
}
var result = guiRect;
result.x /= Screen.width;
result.y /= Screen.height;
result.width /= Screen.width;
result.height /= Screen.height;
result.y = 1 - result.y - result.height;
result.xMin = Mathf.Max(0, result.xMin);
result.yMin = Mathf.Max(0, result.yMin);
result.width = Mathf.Min(1, result.width);
result.height = Mathf.Min(1, result.height);
return result;
}
static DragHandlerDelegate ChooseDragHandler(Rect rect, Vector2 pointer)
{
float extend = DRAG_EXTEND * EditorGUIUtility.pixelsPerPoint;
bool PointerXNear(float point) => Mathf.Abs(point - pointer.x) <= extend;
bool PointerYNear(float point) => Mathf.Abs(point - pointer.y) <= extend;
if (PointerXNear(rect.xMin))
{
if (PointerYNear(rect.yMin)) return DRAG_HANDLER_TOP_LEFT;
if (PointerYNear(rect.yMax)) return DRAG_HANDLER_BOTTOM_LEFT;
return DRAG_HANDLER_LEFT;
}
if (PointerXNear(rect.xMax))
{
if (PointerYNear(rect.yMin)) return DRAG_HANDLER_TOP_RIGHT;
if (PointerYNear(rect.yMax)) return DRAG_HANDLER_BOTTOM_RIGHT;
return DRAG_HANDLER_RIGHT;
}
if (PointerYNear(rect.yMin)) return DRAG_HANDLER_TOP;
if (PointerYNear(rect.yMax)) return DRAG_HANDLER_BOTTOM;
return DRAG_HANDLER_CENTER;
}
static readonly DragHandlerDelegate DRAG_HANDLER_CENTER =
(Vector2 delta, ref Rect rect) => { rect.position += delta; };
static readonly DragHandlerDelegate DRAG_HANDLER_LEFT =
(Vector2 delta, ref Rect rect) => { rect.xMin += delta.x; };
static readonly DragHandlerDelegate DRAG_HANDLER_TOP =
(Vector2 delta, ref Rect rect) => { rect.yMin += delta.y; };
static readonly DragHandlerDelegate DRAG_HANDLER_BOTTOM =
(Vector2 delta, ref Rect rect) => { rect.yMax += delta.y; };
static readonly DragHandlerDelegate DRAG_HANDLER_RIGHT =
(Vector2 delta, ref Rect rect) => { rect.xMax += delta.x; };
static readonly DragHandlerDelegate DRAG_HANDLER_TOP_LEFT =
(Vector2 delta, ref Rect rect) =>
{
rect.xMin += delta.x;
rect.yMin += delta.y;
};
static readonly DragHandlerDelegate DRAG_HANDLER_TOP_RIGHT =
(Vector2 delta, ref Rect rect) =>
{
rect.xMax += delta.x;
rect.yMin += delta.y;
};
static readonly DragHandlerDelegate DRAG_HANDLER_BOTTOM_RIGHT =
(Vector2 delta, ref Rect rect) =>
{
rect.xMax += delta.x;
rect.yMax += delta.y;
};
static readonly DragHandlerDelegate DRAG_HANDLER_BOTTOM_LEFT =
(Vector2 delta, ref Rect rect) =>
{
rect.xMin += delta.x;
rect.yMax += delta.y;
};
}
}
#endif