168 lines
6.0 KiB
C#
168 lines
6.0 KiB
C#
// 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
|