static Vector3 ResizeHandlesGUI(Rect rect, Vector3 pivot, Quaternion rotation, out Vector3 scalePivot)
{
if (Event.current.type == EventType.MouseDown)
{
s_StartRect = rect;
}
scalePivot = pivot;
Vector3 scale = Vector3.one;
Quaternion inverseRotation = Quaternion.Inverse(rotation);
// Loop through the 8 handles (sides and corners) using a nested loop.
// (The loop covers 9 combinations, but the center position is ignored.)
for (int xHandle = 0; xHandle <= 2; xHandle++)
{
for (int yHandle = 0; yHandle <= 2; yHandle++)
{
// Ignore center
if (xHandle == 1 && yHandle == 1)
{
continue;
}
Vector3 origPos = GetRectPointInWorld(s_StartRect, pivot, rotation, xHandle, yHandle);
Vector3 curPos = GetRectPointInWorld(rect, pivot, rotation, xHandle, yHandle);
float size = 0.05f * HandleUtility.GetHandleSize(curPos);
int id = GUIUtility.GetControlID(s_ResizeHandlesHash, FocusType.Passive);
if (GUI.color.a > 0 || GUIUtility.hotControl == id)
{
EditorGUI.BeginChangeCheck();
Vector3 newPos;
EventType typeBefore = Event.current.type;
if (xHandle == 1 || yHandle == 1)
{
// Side resizer (1D)
Vector3 sideDir = (xHandle == 1 ? rotation * Vector3.right * rect.width : rotation * Vector3.up * rect.height);
Vector3 slideDir = (xHandle == 1 ? rotation * Vector3.up : rotation * Vector3.right);
newPos = RectHandles.SideSlider(id, curPos, sideDir, slideDir, size, null, EditorSnapSettings.move);
}
else
{
// Corner handle (2D)
Vector3 outwardsA = rotation * Vector3.right * (xHandle - 1);
Vector3 outwardsB = rotation * Vector3.up * (yHandle - 1);
newPos = RectHandles.CornerSlider(id, curPos, rotation * Vector3.forward, outwardsA, outwardsB, size, RectHandles.RectScalingHandleCap, EditorSnapSettings.move);
}
// Calculate snapping values if applicable
bool supportsRectSnapping = Selection.transforms.Length == 1 &&
UnityEditorInternal.InternalEditorUtility.SupportsRectLayout(Selection.activeTransform) &&
Selection.activeTransform.parent.rotation == rotation;
if (supportsRectSnapping)
{
Transform transform = Selection.activeTransform;
RectTransform rectTransform = transform.GetComponent <RectTransform>();
Transform transformParent = transform.parent;
RectTransform rectTransformParent = transformParent.GetComponent <RectTransform>();
if (typeBefore == EventType.MouseDown && Event.current.type != EventType.MouseDown)
{
RectTransformSnapping.CalculateOffsetSnapValues(transformParent, transform, rectTransformParent, rectTransform, xHandle, yHandle);
}
}
if (EditorGUI.EndChangeCheck())
{
// Resize handles require more fine grained rounding of values than other tools.
// With other tools, the slight rounding is not notizable as long as it's just sub-pixel,
// because the manipulated object is being moved at the same time.
// However, with resize handles, when dragging one edge or corner,
// the opposite is standing still, and even slight rounding can cause shaking/vibration.
// At a fraction of the normal rounding, the shaking is very unlikely to happen though.
ManipulationToolUtility.SetMinDragDifferenceForPos(curPos, 0.1f);
if (supportsRectSnapping)
{
Transform transformParent = Selection.activeTransform.parent;
RectTransform rectParent = transformParent.GetComponent <RectTransform>();
Vector2 snapSize = Vector2.one * HandleUtility.GetHandleSize(newPos) * RectTransformSnapping.kSnapThreshold;
snapSize.x /= (inverseRotation * transformParent.TransformVector(Vector3.right)).x;
snapSize.y /= (inverseRotation * transformParent.TransformVector(Vector3.up)).y;
Vector3 newPosInParent = transformParent.InverseTransformPoint(newPos) - (Vector3)rectParent.rect.min;
Vector3 newPosInParentSnapped = (Vector3)RectTransformSnapping.SnapToGuides(newPosInParent, snapSize) + Vector3.forward * newPosInParent.z;
ManipulationToolUtility.DisableMinDragDifferenceBasedOnSnapping(newPosInParent, newPosInParentSnapped);
newPos = transformParent.TransformPoint(newPosInParentSnapped + (Vector3)rectParent.rect.min);
}
bool scaleFromPivot = Event.current.alt;
bool uniformScaling = Event.current.shift;
if (!scaleFromPivot)
{
scalePivot = GetRectPointInWorld(s_StartRect, pivot, rotation, 2 - xHandle, 2 - yHandle);
}
if (uniformScaling)
{
newPos = Vector3.Project(newPos - scalePivot, origPos - scalePivot) + scalePivot;
}
Vector3 sizeBefore = inverseRotation * (origPos - scalePivot);
Vector3 sizeAfter = inverseRotation * (newPos - scalePivot);
if (xHandle != 1)
{
scale.x = sizeAfter.x / sizeBefore.x;
}
if (yHandle != 1)
{
scale.y = sizeAfter.y / sizeBefore.y;
}
if (uniformScaling)
{
float refScale = (xHandle == 1 ? scale.y : scale.x);
scale = Vector3.one * refScale;
}
if (uniformScaling)
{
float refScale = (xHandle == 1 ? scale.y : scale.x);
scale = Vector3.one * refScale;
}
}
if (xHandle == 0)
{
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingLeft, typeBefore);
}
if (xHandle == 2)
{
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingRight, typeBefore);
}
if (xHandle != 1)
{
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingWidth, typeBefore);
}
if (yHandle == 0)
{
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingBottom, typeBefore);
}
if (yHandle == 2)
{
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingTop, typeBefore);
}
if (yHandle != 1)
{
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingHeight, typeBefore);
}
}
}
}
return(scale);
}