Example #1
0
    /// <summary>
    /// Draw the specified anchor point.
    /// </summary>

    static public void DrawAnchorHandle(UIRect.AnchorPoint anchor, Transform myTrans, Vector3[] myCorners, int side, int id)
    {
        if (!anchor.target)
        {
            return;
        }

        int i0, i1;

        if (side == 0)
        {
            // Left
            i0 = 0;
            i1 = 1;
        }
        else if (side == 1)
        {
            // Top
            i0 = 1;
            i1 = 2;
        }
        else if (side == 2)
        {
            // Right
            i0 = 3;
            i1 = 2;
        }
        else
        {
            // Bottom
            i0 = 0;
            i1 = 3;
        }

        Vector3 myPos = (myCorners[i0] + myCorners[i1]) * 0.5f;

        Vector3[] sides = null;

        if (anchor.rect != null)
        {
            sides = anchor.rect.worldCorners;
        }
        else
        {
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6
            Camera cam = anchor.target.camera;
#else
            Camera cam = anchor.target.GetComponent <Camera>();
#endif
            if (cam != null)
            {
                sides = cam.GetWorldCorners();
            }
        }

        Vector3 theirPos;

        if (sides != null)
        {
            Vector3 v0, v1;

            if (side == 0 || side == 2)
            {
                // Left or right
                v0 = Vector3.Lerp(sides[0], sides[3], anchor.relative);
                v1 = Vector3.Lerp(sides[1], sides[2], anchor.relative);
            }
            else
            {
                // Top or bottom
                v0 = Vector3.Lerp(sides[0], sides[1], anchor.relative);
                v1 = Vector3.Lerp(sides[3], sides[2], anchor.relative);
            }

            theirPos = HandleUtility.ProjectPointLine(myPos, v0, v1);
        }
        else
        {
            theirPos = anchor.target.position;
        }

        NGUIHandles.DrawShadowedLine(myCorners, myPos, theirPos, Color.yellow);

        if (Event.current.GetTypeForControl(id) == EventType.Repaint)
        {
            Vector2 screenPoint = HandleUtility.WorldToGUIPoint(theirPos);
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6
            Rect rect = new Rect(screenPoint.x - 7f, screenPoint.y - 7f, 14f, 14f);
#else
            Rect rect = new Rect(screenPoint.x - 5f, screenPoint.y - 9f, 14f, 14f);
#endif
            if (mYellowDot == null)
            {
                mYellowDot = "sv_label_4";
            }

            Vector3 v0 = HandleUtility.WorldToGUIPoint(myPos);
            Vector3 v1 = HandleUtility.WorldToGUIPoint(theirPos);

            Handles.BeginGUI();

            mYellowDot.Draw(rect, GUIContent.none, id);

            Vector3 diff         = v1 - v0;
            bool    isHorizontal = Mathf.Abs(diff.x) > Mathf.Abs(diff.y);
            float   mag          = diff.magnitude;

            if ((isHorizontal && mag > 60f) || (!isHorizontal && mag > 30f))
            {
                Vector3 pos  = (myPos + theirPos) * 0.5f;
                string  text = anchor.absolute.ToString();

                GUI.color = Color.yellow;

                if (side == 0)
                {
                    if (theirPos.x < myPos.x)
                    {
                        NGUIHandles.DrawCenteredLabel(pos, text);
                    }
                }
                else if (side == 1)
                {
                    if (theirPos.y > myPos.y)
                    {
                        NGUIHandles.DrawCenteredLabel(pos, text);
                    }
                }
                else if (side == 2)
                {
                    if (theirPos.x > myPos.x)
                    {
                        NGUIHandles.DrawCenteredLabel(pos, text);
                    }
                }
                else if (side == 3)
                {
                    if (theirPos.y < myPos.y)
                    {
                        NGUIHandles.DrawCenteredLabel(pos, text);
                    }
                }
                GUI.color = Color.white;
            }
            Handles.EndGUI();
        }
    }
Example #2
0
    /// <summary>
    /// Handles & interaction.
    /// </summary>

    public void OnSceneGUI()
    {
        if (Selection.objects.Length > 1)
        {
            return;
        }

        UICamera cam = UICamera.FindCameraForLayer(mPanel.gameObject.layer);

#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7
        if (cam == null || !cam.cachedCamera.isOrthoGraphic)
        {
            return;
        }
#else
        if (cam == null || !cam.cachedCamera.orthographic)
        {
            return;
        }
#endif

        NGUIEditorTools.HideMoveTool(true);
        if (!UIWidget.showHandles)
        {
            return;
        }

        Event     e    = Event.current;
        int       id   = GUIUtility.GetControlID(s_Hash, FocusType.Passive);
        EventType type = e.GetTypeForControl(id);
        Transform t    = mPanel.cachedTransform;

        Vector3[] handles = UIWidgetInspector.GetHandles(mPanel.worldCorners);

        // Time to figure out what kind of action is underneath the mouse
        UIWidgetInspector.Action actionUnderMouse = mAction;

        Color handlesColor = new Color(0.5f, 0f, 0.5f);
        NGUIHandles.DrawShadowedLine(handles, handles[0], handles[1], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[1], handles[2], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[2], handles[3], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[0], handles[3], handlesColor);

        if (mPanel.isAnchored)
        {
            UIWidgetInspector.DrawAnchorHandle(mPanel.leftAnchor, mPanel.cachedTransform, handles, 0, id);
            UIWidgetInspector.DrawAnchorHandle(mPanel.topAnchor, mPanel.cachedTransform, handles, 1, id);
            UIWidgetInspector.DrawAnchorHandle(mPanel.rightAnchor, mPanel.cachedTransform, handles, 2, id);
            UIWidgetInspector.DrawAnchorHandle(mPanel.bottomAnchor, mPanel.cachedTransform, handles, 3, id);
        }

        if (type == EventType.Repaint)
        {
            bool showDetails = (mAction == UIWidgetInspector.Action.Scale) || NGUISettings.drawGuides;
            if (mAction == UIWidgetInspector.Action.None && e.modifiers == EventModifiers.Control)
            {
                showDetails = true;
            }
            if (NGUITools.GetActive(mPanel) && mPanel.parent == null)
            {
                showDetails = true;
            }
            if (showDetails)
            {
                NGUIHandles.DrawSize(handles, Mathf.RoundToInt(mPanel.width), Mathf.RoundToInt(mPanel.height));
            }
        }

        bool canResize = (mPanel.clipping != UIDrawCall.Clipping.None);

        // NOTE: Remove this part when it's possible to neatly resize rotated anchored panels.
        if (canResize && mPanel.isAnchored)
        {
            Quaternion rot = mPanel.cachedTransform.localRotation;
            if (Quaternion.Angle(rot, Quaternion.identity) > 0.01f)
            {
                canResize = false;
            }
        }

        bool[] resizable = new bool[8];

        resizable[4] = canResize;                    // left
        resizable[5] = canResize;                    // top
        resizable[6] = canResize;                    // right
        resizable[7] = canResize;                    // bottom

        resizable[0] = resizable[7] && resizable[4]; // bottom-left
        resizable[1] = resizable[5] && resizable[4]; // top-left
        resizable[2] = resizable[5] && resizable[6]; // top-right
        resizable[3] = resizable[7] && resizable[6]; // bottom-right

        UIWidget.Pivot pivotUnderMouse = UIWidgetInspector.GetPivotUnderMouse(handles, e, resizable, true, ref actionUnderMouse);

        switch (type)
        {
        case EventType.Repaint:
        {
            Vector3 v0 = HandleUtility.WorldToGUIPoint(handles[0]);
            Vector3 v2 = HandleUtility.WorldToGUIPoint(handles[2]);

            if ((v2 - v0).magnitude > 60f)
            {
                Vector3 v1 = HandleUtility.WorldToGUIPoint(handles[1]);
                Vector3 v3 = HandleUtility.WorldToGUIPoint(handles[3]);

                Handles.BeginGUI();
                {
                    for (int i = 0; i < 4; ++i)
                    {
                        DrawKnob(handles[i], id, resizable[i]);
                    }

                    if (Mathf.Abs(v1.y - v0.y) > 80f)
                    {
                        if (mPanel.leftAnchor.target == null || mPanel.leftAnchor.absolute != 0)
                        {
                            DrawKnob(handles[4], id, resizable[4]);
                        }

                        if (mPanel.rightAnchor.target == null || mPanel.rightAnchor.absolute != 0)
                        {
                            DrawKnob(handles[6], id, resizable[6]);
                        }
                    }

                    if (Mathf.Abs(v3.x - v0.x) > 80f)
                    {
                        if (mPanel.topAnchor.target == null || mPanel.topAnchor.absolute != 0)
                        {
                            DrawKnob(handles[5], id, resizable[5]);
                        }

                        if (mPanel.bottomAnchor.target == null || mPanel.bottomAnchor.absolute != 0)
                        {
                            DrawKnob(handles[7], id, resizable[7]);
                        }
                    }
                }
                Handles.EndGUI();
            }
        }
        break;

        case EventType.MouseDown:
        {
            if (actionUnderMouse != UIWidgetInspector.Action.None)
            {
                mStartMouse     = e.mousePosition;
                mAllowSelection = true;

                if (e.button == 1)
                {
                    if (e.modifiers == 0)
                    {
                        GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                        e.Use();
                    }
                }
                else if (e.button == 0 && actionUnderMouse != UIWidgetInspector.Action.None &&
                         UIWidgetInspector.Raycast(handles, out mStartDrag))
                {
                    mWorldPos             = t.position;
                    mLocalPos             = t.localPosition;
                    mStartRot             = t.localRotation.eulerAngles;
                    mStartDir             = mStartDrag - t.position;
                    mStartCR              = mPanel.baseClipRegion;
                    mDragPivot            = pivotUnderMouse;
                    mActionUnderMouse     = actionUnderMouse;
                    GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                    e.Use();
                }
            }
        }
        break;

        case EventType.MouseUp:
        {
            if (GUIUtility.hotControl == id)
            {
                GUIUtility.hotControl      = 0;
                GUIUtility.keyboardControl = 0;

                if (e.button < 2)
                {
                    bool handled = false;

                    if (e.button == 1)
                    {
                        // Right-click: Open a context menu listing all widgets underneath
                        NGUIEditorTools.ShowSpriteSelectionMenu(e.mousePosition);
                        handled = true;
                    }
                    else if (mAction == UIWidgetInspector.Action.None)
                    {
                        if (mAllowSelection)
                        {
                            // Left-click: Select the topmost widget
                            NGUIEditorTools.SelectWidget(e.mousePosition);
                            handled = true;
                        }
                    }
                    else
                    {
                        // Finished dragging something
                        Vector3 pos = t.localPosition;
                        pos.x           = Mathf.Round(pos.x);
                        pos.y           = Mathf.Round(pos.y);
                        pos.z           = Mathf.Round(pos.z);
                        t.localPosition = pos;
                        handled         = true;
                    }

                    if (handled)
                    {
                        e.Use();
                    }
                }

                // Clear the actions
                mActionUnderMouse = UIWidgetInspector.Action.None;
                mAction           = UIWidgetInspector.Action.None;
            }
            else if (mAllowSelection)
            {
                List <UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition);
                if (widgets.Count > 0)
                {
                    Selection.activeGameObject = widgets[0].gameObject;
                }
            }
            mAllowSelection = true;
        }
        break;

        case EventType.MouseDrag:
        {
            // Prevent selection once the drag operation begins
            bool dragStarted = (e.mousePosition - mStartMouse).magnitude > 3f;
            if (dragStarted)
            {
                mAllowSelection = false;
            }

            if (GUIUtility.hotControl == id)
            {
                e.Use();

                if (mAction != UIWidgetInspector.Action.None || mActionUnderMouse != UIWidgetInspector.Action.None)
                {
                    Vector3 pos;

                    if (UIWidgetInspector.Raycast(handles, out pos))
                    {
                        if (mAction == UIWidgetInspector.Action.None && mActionUnderMouse != UIWidgetInspector.Action.None)
                        {
                            // Wait until the mouse moves by more than a few pixels
                            if (dragStarted)
                            {
                                if (mActionUnderMouse == UIWidgetInspector.Action.Move)
                                {
                                    NGUISnap.Recalculate(mPanel);
                                }
                                else if (mActionUnderMouse == UIWidgetInspector.Action.Rotate)
                                {
                                    mStartRot = t.localRotation.eulerAngles;
                                    mStartDir = mStartDrag - t.position;
                                }
                                else if (mActionUnderMouse == UIWidgetInspector.Action.Scale)
                                {
                                    mStartCR   = mPanel.baseClipRegion;
                                    mDragPivot = pivotUnderMouse;
                                }
                                mAction = actionUnderMouse;
                            }
                        }

                        if (mAction != UIWidgetInspector.Action.None)
                        {
                            NGUIEditorTools.RegisterUndo("Change Rect", t);
                            NGUIEditorTools.RegisterUndo("Change Rect", mPanel);

                            if (mAction == UIWidgetInspector.Action.Move)
                            {
                                Vector3 before      = t.position;
                                Vector3 beforeLocal = t.localPosition;
                                t.position = mWorldPos + (pos - mStartDrag);
                                pos        = NGUISnap.Snap(t.localPosition, mPanel.localCorners,
                                                           e.modifiers != EventModifiers.Control) - beforeLocal;
                                t.position = before;

                                NGUIMath.MoveRect(mPanel, pos.x, pos.y);
                            }
                            else if (mAction == UIWidgetInspector.Action.Rotate)
                            {
                                Vector3 dir   = pos - t.position;
                                float   angle = Vector3.Angle(mStartDir, dir);

                                if (angle > 0f)
                                {
                                    float dot = Vector3.Dot(Vector3.Cross(mStartDir, dir), t.forward);
                                    if (dot < 0f)
                                    {
                                        angle = -angle;
                                    }
                                    angle = mStartRot.z + angle;
                                    angle = (NGUISnap.allow && e.modifiers != EventModifiers.Control) ?
                                            Mathf.Round(angle / 15f) * 15f : Mathf.Round(angle);
                                    t.localRotation = Quaternion.Euler(mStartRot.x, mStartRot.y, angle);
                                }
                            }
                            else if (mAction == UIWidgetInspector.Action.Scale)
                            {
                                // World-space delta since the drag started
                                Vector3 delta = pos - mStartDrag;

                                // Adjust the widget's position and scale based on the delta, restricted by the pivot
                                AdjustClipping(mPanel, mLocalPos, mStartCR, delta, mDragPivot);
                            }
                        }
                    }
                }
            }
        }
        break;

        case EventType.KeyDown:
        {
            if (e.keyCode == KeyCode.UpArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
                NGUIMath.MoveRect(mPanel, 0f, 1f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.DownArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
                NGUIMath.MoveRect(mPanel, 0f, -1f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.LeftArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
                NGUIMath.MoveRect(mPanel, -1f, 0f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.RightArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mPanel);
                NGUIMath.MoveRect(mPanel, 1f, 0f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.Escape)
            {
                if (GUIUtility.hotControl == id)
                {
                    if (mAction != UIWidgetInspector.Action.None)
                    {
                        Undo.PerformUndo();
                    }

                    GUIUtility.hotControl      = 0;
                    GUIUtility.keyboardControl = 0;

                    mActionUnderMouse = UIWidgetInspector.Action.None;
                    mAction           = UIWidgetInspector.Action.None;
                    e.Use();
                }
                else
                {
                    Selection.activeGameObject = null;
                }
            }
        }
        break;
        }
    }
Example #3
0
    /// <summary>
    /// Draw the on-screen selection, knobs, and handle all interaction logic.
    /// </summary>

    public void OnSceneGUI()
    {
        NGUIEditorTools.HideMoveTool(true);
        if (!UIWidget.showHandles)
        {
            return;
        }

        mWidget = target as UIWidget;

        Transform t = mWidget.cachedTransform;

        Event     e    = Event.current;
        int       id   = GUIUtility.GetControlID(s_Hash, FocusType.Passive);
        EventType type = e.GetTypeForControl(id);

        Action actionUnderMouse = mAction;

        Vector3[] handles = GetHandles(mWidget.worldCorners);

        NGUIHandles.DrawShadowedLine(handles, handles[0], handles[1], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[1], handles[2], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[2], handles[3], handlesColor);
        NGUIHandles.DrawShadowedLine(handles, handles[0], handles[3], handlesColor);

        // If the widget is anchored, draw the anchors
        if (mWidget.isAnchored)
        {
            DrawAnchorHandle(mWidget.leftAnchor, mWidget.cachedTransform, handles, 0, id);
            DrawAnchorHandle(mWidget.topAnchor, mWidget.cachedTransform, handles, 1, id);
            DrawAnchorHandle(mWidget.rightAnchor, mWidget.cachedTransform, handles, 2, id);
            DrawAnchorHandle(mWidget.bottomAnchor, mWidget.cachedTransform, handles, 3, id);
        }

        if (type == EventType.Repaint)
        {
            bool showDetails = (mAction == UIWidgetInspector.Action.Scale) || NGUISettings.drawGuides;
            if (mAction == UIWidgetInspector.Action.None && e.modifiers == EventModifiers.Control)
            {
                showDetails = true;
            }
            if (NGUITools.GetActive(mWidget) && mWidget.parent == null)
            {
                showDetails = true;
            }
            if (showDetails)
            {
                NGUIHandles.DrawSize(handles, mWidget.width, mWidget.height);
            }
        }

        // Presence of the legacy stretch component prevents resizing
        bool canResize = (mWidget.GetComponent <UIStretch>() == null);

        bool[] resizable = new bool[8];

        resizable[4] = canResize;               // left
        resizable[5] = canResize;               // top
        resizable[6] = canResize;               // right
        resizable[7] = canResize;               // bottom

        UILabel lbl = mWidget as UILabel;

        if (lbl != null)
        {
            if (lbl.overflowMethod == UILabel.Overflow.ResizeFreely)
            {
                resizable[4] = false;                   // left
                resizable[5] = false;                   // top
                resizable[6] = false;                   // right
                resizable[7] = false;                   // bottom
            }
            else if (lbl.overflowMethod == UILabel.Overflow.ResizeHeight)
            {
                resizable[5] = false;                   // top
                resizable[7] = false;                   // bottom
            }
        }

        if (mWidget.keepAspectRatio == UIWidget.AspectRatioSource.BasedOnHeight)
        {
            resizable[4] = false;
            resizable[6] = false;
        }
        else if (mWidget.keepAspectRatio == UIWidget.AspectRatioSource.BasedOnWidth)
        {
            resizable[5] = false;
            resizable[7] = false;
        }

        resizable[0] = resizable[7] && resizable[4];         // bottom-left
        resizable[1] = resizable[5] && resizable[4];         // top-left
        resizable[2] = resizable[5] && resizable[6];         // top-right
        resizable[3] = resizable[7] && resizable[6];         // bottom-right

        UIWidget.Pivot pivotUnderMouse = GetPivotUnderMouse(handles, e, resizable, true, ref actionUnderMouse);

        switch (type)
        {
        case EventType.Repaint:
        {
            Vector3 v0 = HandleUtility.WorldToGUIPoint(handles[0]);
            Vector3 v2 = HandleUtility.WorldToGUIPoint(handles[2]);

            if ((v2 - v0).magnitude > 60f)
            {
                Vector3 v1 = HandleUtility.WorldToGUIPoint(handles[1]);
                Vector3 v3 = HandleUtility.WorldToGUIPoint(handles[3]);

                Handles.BeginGUI();
                {
                    for (int i = 0; i < 4; ++i)
                    {
                        DrawKnob(handles[i], mWidget.pivot == pivotPoints[i], resizable[i], id);
                    }

                    if ((v1 - v0).magnitude > 80f)
                    {
                        if (mWidget.leftAnchor.target == null || mWidget.leftAnchor.absolute != 0)
                        {
                            DrawKnob(handles[4], mWidget.pivot == pivotPoints[4], resizable[4], id);
                        }

                        if (mWidget.rightAnchor.target == null || mWidget.rightAnchor.absolute != 0)
                        {
                            DrawKnob(handles[6], mWidget.pivot == pivotPoints[6], resizable[6], id);
                        }
                    }

                    if ((v3 - v0).magnitude > 80f)
                    {
                        if (mWidget.topAnchor.target == null || mWidget.topAnchor.absolute != 0)
                        {
                            DrawKnob(handles[5], mWidget.pivot == pivotPoints[5], resizable[5], id);
                        }

                        if (mWidget.bottomAnchor.target == null || mWidget.bottomAnchor.absolute != 0)
                        {
                            DrawKnob(handles[7], mWidget.pivot == pivotPoints[7], resizable[7], id);
                        }
                    }
                }
                Handles.EndGUI();
            }
        }
        break;

        case EventType.MouseDown:
        {
            if (actionUnderMouse != Action.None)
            {
                mStartMouse     = e.mousePosition;
                mAllowSelection = true;

                if (e.button == 1)
                {
                    if (e.modifiers == 0)
                    {
                        GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                        e.Use();
                    }
                }
                else if (e.button == 0 && actionUnderMouse != Action.None && Raycast(handles, out mStartDrag))
                {
                    mWorldPos      = t.position;
                    mLocalPos      = t.localPosition;
                    mStartRot      = t.localRotation.eulerAngles;
                    mStartDir      = mStartDrag - t.position;
                    mStartWidth    = mWidget.width;
                    mStartHeight   = mWidget.height;
                    mStartLeft.x   = mWidget.leftAnchor.relative;
                    mStartLeft.y   = mWidget.leftAnchor.absolute;
                    mStartRight.x  = mWidget.rightAnchor.relative;
                    mStartRight.y  = mWidget.rightAnchor.absolute;
                    mStartBottom.x = mWidget.bottomAnchor.relative;
                    mStartBottom.y = mWidget.bottomAnchor.absolute;
                    mStartTop.x    = mWidget.topAnchor.relative;
                    mStartTop.y    = mWidget.topAnchor.absolute;

                    mDragPivot            = pivotUnderMouse;
                    mActionUnderMouse     = actionUnderMouse;
                    GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                    e.Use();
                }
            }
        }
        break;

        case EventType.MouseDrag:
        {
            // Prevent selection once the drag operation begins
            bool dragStarted = (e.mousePosition - mStartMouse).magnitude > 3f;
            if (dragStarted)
            {
                mAllowSelection = false;
            }

            if (GUIUtility.hotControl == id)
            {
                e.Use();

                if (mAction != Action.None || mActionUnderMouse != Action.None)
                {
                    Vector3 pos;

                    if (Raycast(handles, out pos))
                    {
                        if (mAction == Action.None && mActionUnderMouse != Action.None)
                        {
                            // Wait until the mouse moves by more than a few pixels
                            if (dragStarted)
                            {
                                if (mActionUnderMouse == Action.Move)
                                {
                                    NGUISnap.Recalculate(mWidget);
                                }
                                else if (mActionUnderMouse == Action.Rotate)
                                {
                                    mStartRot = t.localRotation.eulerAngles;
                                    mStartDir = mStartDrag - t.position;
                                }
                                else if (mActionUnderMouse == Action.Scale)
                                {
                                    mStartWidth  = mWidget.width;
                                    mStartHeight = mWidget.height;
                                    mDragPivot   = pivotUnderMouse;
                                }
                                mAction = actionUnderMouse;
                            }
                        }

                        if (mAction != Action.None)
                        {
                            NGUIEditorTools.RegisterUndo("Change Rect", t);
                            NGUIEditorTools.RegisterUndo("Change Rect", mWidget);

                            // Reset the widget before adjusting anything
                            t.position     = mWorldPos;
                            mWidget.width  = mStartWidth;
                            mWidget.height = mStartHeight;
                            mWidget.leftAnchor.Set(mStartLeft.x, mStartLeft.y);
                            mWidget.rightAnchor.Set(mStartRight.x, mStartRight.y);
                            mWidget.bottomAnchor.Set(mStartBottom.x, mStartBottom.y);
                            mWidget.topAnchor.Set(mStartTop.x, mStartTop.y);

                            if (mAction == Action.Move)
                            {
                                // Move the widget
                                t.position = mWorldPos + (pos - mStartDrag);

                                // Snap the widget
                                Vector3 after = NGUISnap.Snap(t.localPosition, mWidget.localCorners, e.modifiers != EventModifiers.Control);

                                // Calculate the final delta
                                Vector3 localDelta = (after - mLocalPos);

                                // Restore the position
                                t.position = mWorldPos;

                                // Adjust the widget by the delta
                                NGUIMath.MoveRect(mWidget, localDelta.x, localDelta.y);
                            }
                            else if (mAction == Action.Rotate)
                            {
                                Vector3 dir   = pos - t.position;
                                float   angle = Vector3.Angle(mStartDir, dir);

                                if (angle > 0f)
                                {
                                    float dot = Vector3.Dot(Vector3.Cross(mStartDir, dir), t.forward);
                                    if (dot < 0f)
                                    {
                                        angle = -angle;
                                    }
                                    angle = mStartRot.z + angle;
                                    angle = (NGUISnap.allow && e.modifiers != EventModifiers.Control) ?
                                            Mathf.Round(angle / 15f) * 15f : Mathf.Round(angle);
                                    t.localRotation = Quaternion.Euler(mStartRot.x, mStartRot.y, angle);
                                }
                            }
                            else if (mAction == Action.Scale)
                            {
                                // Move the widget
                                t.position = mWorldPos + (pos - mStartDrag);

                                // Calculate the final delta
                                Vector3 localDelta = (t.localPosition - mLocalPos);

                                // Restore the position
                                t.position = mWorldPos;

                                // Adjust the widget's position and scale based on the delta, restricted by the pivot
                                NGUIMath.ResizeWidget(mWidget, mDragPivot, localDelta.x, localDelta.y, 2, 2);
                                ReEvaluateAnchorType();
                            }
                        }
                    }
                }
            }
        }
        break;

        case EventType.MouseUp:
        {
            if (GUIUtility.hotControl == id)
            {
                GUIUtility.hotControl      = 0;
                GUIUtility.keyboardControl = 0;

                if (e.button < 2)
                {
                    bool handled = false;

                    if (e.button == 1)
                    {
                        // Right-click: Open a context menu listing all widgets underneath
                        NGUIEditorTools.ShowSpriteSelectionMenu(e.mousePosition);
                        handled = true;
                    }
                    else if (mAction == Action.None)
                    {
                        if (mAllowSelection)
                        {
                            // Left-click: Select the topmost widget
                            NGUIEditorTools.SelectWidget(e.mousePosition);
                            handled = true;
                        }
                    }
                    else
                    {
                        // Finished dragging something
                        Vector3 pos = t.localPosition;
                        pos.x           = Mathf.Round(pos.x);
                        pos.y           = Mathf.Round(pos.y);
                        pos.z           = Mathf.Round(pos.z);
                        t.localPosition = pos;
                        handled         = true;
                    }

                    if (handled)
                    {
                        e.Use();
                    }
                }

                // Clear the actions
                mActionUnderMouse = Action.None;
                mAction           = Action.None;
            }
            else if (mAllowSelection)
            {
                BetterList <UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition);
                if (widgets.size > 0)
                {
                    Selection.activeGameObject = widgets[0].gameObject;
                }
            }
            mAllowSelection = true;
        }
        break;

        case EventType.KeyDown:
        {
            if (e.keyCode == KeyCode.UpArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, 0f, 1f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.DownArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, 0f, -1f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.LeftArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, -1f, 0f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.RightArrow)
            {
                NGUIEditorTools.RegisterUndo("Nudge Rect", t);
                NGUIEditorTools.RegisterUndo("Nudge Rect", mWidget);
                NGUIMath.MoveRect(mWidget, 1f, 0f);
                e.Use();
            }
            else if (e.keyCode == KeyCode.Escape)
            {
                if (GUIUtility.hotControl == id)
                {
                    if (mAction != Action.None)
                    {
                        Undo.PerformUndo();
                    }

                    GUIUtility.hotControl      = 0;
                    GUIUtility.keyboardControl = 0;

                    mActionUnderMouse = Action.None;
                    mAction           = Action.None;
                    e.Use();
                }
                else
                {
                    Selection.activeGameObject = null;
                }
            }
        }
        break;
        }
    }
Example #4
0
    /// <summary>
    /// Make it possible to easily drag the transform around.
    /// </summary>

    public void OnSceneGUI()
    {
        //NGUIEditorTools.HideMoveTool(true);
        if (!UIWidget.showHandles)
        {
            return;
        }

        MonoBehaviour mb = target as MonoBehaviour;

        if (mb.GetComponent <UIWidget>() != null)
        {
            return;
        }
        if (mb.GetComponent <UIPanel>() != null)
        {
            return;
        }

        Transform t = mb.transform;

        UIWidget[] widgets = t.GetComponentsInChildren <UIWidget>();

        Event     e            = Event.current;
        int       id           = GUIUtility.GetControlID(mHash, FocusType.Passive);
        EventType type         = e.GetTypeForControl(id);
        bool      isWithinRect = false;

        Vector3[] corners = null;
        Vector3[] handles = null;

        if (widgets.Length > 0)
        {
            Matrix4x4 worldToLocal = t.worldToLocalMatrix;
            Matrix4x4 localToWorld = t.localToWorldMatrix;
            Bounds    bounds       = new Bounds();

            // Calculate the local bounds
            for (int i = 0; i < widgets.Length; ++i)
            {
                Vector3[] wcs = widgets[i].worldCorners;

                for (int b = 0; b < 4; ++b)
                {
                    wcs[b] = worldToLocal.MultiplyPoint3x4(wcs[b]);
                    if (i == 0 && b == 0)
                    {
                        bounds = new Bounds(wcs[b], Vector3.zero);
                    }
                    else
                    {
                        bounds.Encapsulate(wcs[b]);
                    }
                }
            }

            // Calculate the 4 local corners
            Vector3 v0 = bounds.min;
            Vector3 v1 = bounds.max;

            float z = Mathf.Min(v0.z, v1.z);
            corners    = new Vector3[4];
            corners[0] = new Vector3(v0.x, v0.y, z);
            corners[1] = new Vector3(v0.x, v1.y, z);
            corners[2] = new Vector3(v1.x, v1.y, z);
            corners[3] = new Vector3(v1.x, v0.y, z);

            // Transform the 4 corners into world space
            for (int i = 0; i < 4; ++i)
            {
                corners[i] = localToWorld.MultiplyPoint3x4(corners[i]);
            }

            handles = new Vector3[8];

            handles[0] = corners[0];
            handles[1] = corners[1];
            handles[2] = corners[2];
            handles[3] = corners[3];

            handles[4] = (corners[0] + corners[1]) * 0.5f;
            handles[5] = (corners[1] + corners[2]) * 0.5f;
            handles[6] = (corners[2] + corners[3]) * 0.5f;
            handles[7] = (corners[0] + corners[3]) * 0.5f;

            Color handlesColor = UIWidgetInspector.handlesColor;
            NGUIHandles.DrawShadowedLine(handles, handles[0], handles[1], handlesColor);
            NGUIHandles.DrawShadowedLine(handles, handles[1], handles[2], handlesColor);
            NGUIHandles.DrawShadowedLine(handles, handles[2], handles[3], handlesColor);
            NGUIHandles.DrawShadowedLine(handles, handles[0], handles[3], handlesColor);

            isWithinRect = mIsDragging || (e.modifiers == 0 &&
                                           NGUIEditorTools.SceneViewDistanceToRectangle(corners, e.mousePosition) == 0f);
#if !UNITY_3_5
            // Change the mouse cursor to a more appropriate one
            Vector2[] screenPos = new Vector2[8];
            for (int i = 0; i < 8; ++i)
            {
                screenPos[i] = HandleUtility.WorldToGUIPoint(handles[i]);
            }

            bounds = new Bounds(screenPos[0], Vector3.zero);
            for (int i = 1; i < 8; ++i)
            {
                bounds.Encapsulate(screenPos[i]);
            }

            // Change the cursor to a move arrow when it's within the screen rectangle
            Vector2 min  = bounds.min;
            Vector2 max  = bounds.max;
            Rect    rect = new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
            UIWidgetInspector.SetCursorRect(rect, isWithinRect ? MouseCursor.MoveArrow : MouseCursor.Arrow);
#endif
        }

        switch (type)
        {
        case EventType.Repaint:
        {
            if (handles != null)
            {
                Vector3 v0 = HandleUtility.WorldToGUIPoint(handles[0]);
                Vector3 v2 = HandleUtility.WorldToGUIPoint(handles[2]);

                if ((v2 - v0).magnitude > 60f)
                {
                    Vector3 v1 = HandleUtility.WorldToGUIPoint(handles[1]);
                    Vector3 v3 = HandleUtility.WorldToGUIPoint(handles[3]);

                    Handles.BeginGUI();
                    {
                        for (int i = 0; i < 4; ++i)
                        {
                            UIWidgetInspector.DrawKnob(handles[i], false, false, id);
                        }

                        if (Mathf.Abs(v1.y - v0.y) > 80f)
                        {
                            UIWidgetInspector.DrawKnob(handles[4], false, false, id);
                            UIWidgetInspector.DrawKnob(handles[6], false, false, id);
                        }

                        if (Mathf.Abs(v3.x - v0.x) > 80f)
                        {
                            UIWidgetInspector.DrawKnob(handles[5], false, false, id);
                            UIWidgetInspector.DrawKnob(handles[7], false, false, id);
                        }
                    }
                    Handles.EndGUI();
                }
            }
        }
        break;

        case EventType.MouseDown:
        {
            mAllowSelection = true;
            mStartMouse     = e.mousePosition;

            if (e.button == 1 && isWithinRect)
            {
                GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                e.Use();
            }
            else if (e.button == 0 && isWithinRect && corners != null && UIWidgetInspector.Raycast(corners, out mStartDrag))
            {
                mCanDrag              = true;
                mStartPos             = t.position;
                GUIUtility.hotControl = GUIUtility.keyboardControl = id;
                e.Use();
            }
        }
        break;

        case EventType.MouseDrag:
        {
            // Prevent selection once the drag operation begins
            bool dragStarted = (e.mousePosition - mStartMouse).magnitude > 3f;
            if (dragStarted)
            {
                mAllowSelection = false;
            }

            if (GUIUtility.hotControl == id)
            {
                e.Use();

                if (mCanDrag)
                {
                    Vector3 pos;

                    if (corners != null & UIWidgetInspector.Raycast(corners, out pos))
                    {
                        // Wait until the mouse moves by more than a few pixels
                        if (!mIsDragging && dragStarted)
                        {
                            NGUIEditorTools.RegisterUndo("Move " + t.name, t);
                            mStartPos   = t.position;
                            mIsDragging = true;
                        }

                        if (mIsDragging)
                        {
                            t.position      = mStartPos + (pos - mStartDrag);
                            pos             = t.localPosition;
                            pos.x           = Mathf.Round(pos.x);
                            pos.y           = Mathf.Round(pos.y);
                            pos.z           = Mathf.Round(pos.z);
                            t.localPosition = pos;
                        }
                    }
                }
            }
        }
        break;

        case EventType.MouseUp:
        {
            if (GUIUtility.hotControl == id)
            {
                GUIUtility.hotControl      = 0;
                GUIUtility.keyboardControl = 0;

                if (e.button == 0)
                {
                    if (mIsDragging)
                    {
                        mIsDragging = false;
                        Vector3 pos = t.localPosition;
                        pos.x           = Mathf.Round(pos.x);
                        pos.y           = Mathf.Round(pos.y);
                        pos.z           = Mathf.Round(pos.z);
                        t.localPosition = pos;
                    }
                    else if (mAllowSelection)
                    {
                        // Left-click: Select the topmost widget
                        NGUIEditorTools.SelectWidget(e.mousePosition);
                        e.Use();
                    }
                    e.Use();
                }
                else
                {
                    // Right-click: Open a context menu listing all widgets underneath
                    NGUIEditorTools.ShowSpriteSelectionMenu(e.mousePosition);
                    e.Use();
                }
                mCanDrag = false;
            }
        }
        break;

        case EventType.KeyDown:
        {
            if (e.keyCode == KeyCode.UpArrow)
            {
                Vector3 pos = t.localPosition;
                pos.y          += 1f;
                t.localPosition = pos;
                e.Use();
            }
            else if (e.keyCode == KeyCode.DownArrow)
            {
                Vector3 pos = t.localPosition;
                pos.y          -= 1f;
                t.localPosition = pos;
                e.Use();
            }
            else if (e.keyCode == KeyCode.LeftArrow)
            {
                Vector3 pos = t.localPosition;
                pos.x          -= 1f;
                t.localPosition = pos;
                e.Use();
            }
            else if (e.keyCode == KeyCode.RightArrow)
            {
                Vector3 pos = t.localPosition;
                pos.x          += 1f;
                t.localPosition = pos;
                e.Use();
            }
            else if (e.keyCode == KeyCode.Escape)
            {
                if (GUIUtility.hotControl == id)
                {
                    if (mIsDragging)
                    {
                        mIsDragging = false;
                        t.position  = mStartPos;
                    }

                    GUIUtility.hotControl      = 0;
                    GUIUtility.keyboardControl = 0;
                    e.Use();
                }
                else
                {
                    Selection.activeGameObject = null;
                }
            }
        }
        break;
        }
    }