/** * A 2D GUI view position handle. * @param id The Handle id. * @param position The position in GUI coordinates. * @param size How large in pixels to draw this handle. */ public static Vector2 PositionHandle2d(int id, Vector2 position, int size) { int width = size / 4; var evt = Event.current; Rect handleRectUp = new Rect(position.x - width / 2, position.y - size - HANDLE_PADDING, width, size + HANDLE_PADDING); Rect handleRectRight = new Rect(position.x, position.y - width / 2, size, width + HANDLE_PADDING); Handles.color = Color.yellow; Handles.CircleHandleCap(-1, position, Quaternion.identity, width / 2f, Event.current.type); Handles.color = k_HandleColorUp; // Y Line Handles.DrawLine(position, position - Vector2.up * size); // Y Cone if (position.y - size > 0f) { Handles.ConeHandleCap(0, ((Vector3)((position - Vector2.up * size))) - ConeDepth, QuaternionUp, width / 2, evt.type); } Handles.color = k_HandleColorRight; // X Line Handles.DrawLine(position, position + Vector2.right * size); // X Cap if (position.y > 0f) { Handles.ConeHandleCap(0, ((Vector3)((position + Vector2.right * size))) - ConeDepth, QuaternionRight, width / 2, evt.type); } // If a Tool already is engaged and it's not this one, bail. if (currentId >= 0 && currentId != id) { return(position); } Vector2 mousePosition = evt.mousePosition; Vector2 newPosition = position; if (currentId == id) { switch (evt.type) { case EventType.MouseDrag: newPosition = axisConstraint.Mask(mousePosition + handleOffset) + axisConstraint.InverseMask(position); break; case EventType.MouseUp: case EventType.Ignore: currentId = -1; break; } } else { if (evt.type == EventType.MouseDown && ((!limitToLeftButton && evt.button != MIDDLE_MOUSE_BUTTON) || evt.button == LEFT_MOUSE_BUTTON)) { if (Vector2.Distance(mousePosition, position) < width / 2f) { currentId = id; handleOffset = position - mousePosition; axisConstraint = new HandleConstraint2D(1, 1); } else if (handleRectRight.Contains(mousePosition)) { currentId = id; handleOffset = position - mousePosition; axisConstraint = new HandleConstraint2D(1, 0); } else if (handleRectUp.Contains(mousePosition)) { currentId = id; handleOffset = position - mousePosition; axisConstraint = new HandleConstraint2D(0, 1); } } } return(newPosition); }
/// <summary> /// Scale handle in 2d space. /// </summary> /// <param name="id"></param> /// <param name="position"></param> /// <param name="scale"></param> /// <param name="size"></param> /// <returns></returns> public static Vector2 ScaleHandle2d(int id, Vector2 position, Vector2 scale, int size) { Event evt = Event.current; Vector2 mousePosition = evt.mousePosition; int width = size / 4; Handles.color = k_HandleColorUp; Handles.DrawLine(position, position - Vector2.up * size * scale.y); if (position.y - size > 0f) { Handles.CubeHandleCap(0, ((Vector3)((position - Vector2.up * scale.y * size))) - Vector3.forward * 16, QuaternionUp, width / 3, evt.type); } Handles.color = k_HandleColorRight; Handles.DrawLine(position, position + Vector2.right * size * scale.x); if (position.y > 0f) { Handles.CubeHandleCap(0, ((Vector3)((position + Vector2.right * scale.x * size))) - Vector3.forward * 16, Quaternion.Euler(Vector3.up * 90f), width / 3f, evt.type); } Handles.color = k_HandleColorScale; Handles.CubeHandleCap(0, ((Vector3)position) - Vector3.forward * 16, QuaternionUp, width / 2f, evt.type); // If a Tool already is engaged and it's not this one, bail. if (currentId >= 0 && currentId != id) { return(scale); } Rect handleRectUp = new Rect(position.x - width / 2f, position.y - size - HANDLE_PADDING, width, size + HANDLE_PADDING); Rect handleRectRight = new Rect(position.x, position.y - width / 2f, size + 8, width); Rect handleRectCenter = new Rect(position.x - width / 2f, position.y - width / 2f, width, width); if (currentId == id) { switch (evt.type) { case EventType.MouseDrag: Vector2 diff = axisConstraint.Mask(mousePosition - initialMousePosition); diff.x += size; diff.y = -diff.y; // gui space Y is opposite-world diff.y += size; scale = diff / size; if (axisConstraint == HandleConstraint2D.None) { scale.x = Mathf.Min(scale.x, scale.y); scale.y = Mathf.Min(scale.x, scale.y); } break; case EventType.MouseUp: case EventType.Ignore: currentId = -1; break; } } else { if (evt.type == EventType.MouseDown && ((!limitToLeftButton && evt.button != MIDDLE_MOUSE_BUTTON) || evt.button == LEFT_MOUSE_BUTTON)) { if (handleRectCenter.Contains(mousePosition)) { currentId = id; handleOffset = position - mousePosition; initialMousePosition = mousePosition; axisConstraint = new HandleConstraint2D(1, 1); } else if (handleRectRight.Contains(mousePosition)) { currentId = id; handleOffset = position - mousePosition; initialMousePosition = mousePosition; axisConstraint = new HandleConstraint2D(1, 0); } else if (handleRectUp.Contains(mousePosition)) { currentId = id; handleOffset = position - mousePosition; initialMousePosition = mousePosition; axisConstraint = new HandleConstraint2D(0, 1); } } } return(scale); }