/// <summary> /// Handles & interaction. /// </summary> public void OnSceneGUI () { 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; } }
/// <summary> /// Handles & interaction. /// </summary> public void OnSceneGUI () { 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; bool canResize = (mPanel.clipping != UIDrawCall.Clipping.None); UIWidget.Pivot pivotUnderMouse = UIWidgetInspector.GetPivotUnderMouse(handles, e, canResize, ref actionUnderMouse); Handles.color = new Color(0.5f, 0f, 0.5f); Handles.DrawLine(handles[0], handles[1]); Handles.DrawLine(handles[1], handles[2]); Handles.DrawLine(handles[2], handles[3]); Handles.DrawLine(handles[0], handles[3]); switch (type) { case EventType.Repaint: { Vector3 bottomLeft = HandleUtility.WorldToGUIPoint(handles[0]); Vector3 topRight = HandleUtility.WorldToGUIPoint(handles[2]); Vector3 diff = topRight - bottomLeft; float mag = diff.magnitude; if (mag > 140f) { Handles.BeginGUI(); for (int i = 0; i < 8; ++i) DrawKnob(handles[i], id); Handles.EndGUI(); } else if (mag > 40f) { Handles.BeginGUI(); for (int i = 0; i < 4; ++i) DrawKnob(handles[i], id); Handles.EndGUI(); } } break; case EventType.MouseDown: { 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)) { mStartPos = t.position; mStartRot = t.localRotation.eulerAngles; mStartDir = mStartDrag - t.position; mStartCR = mPanel.clipRange; 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) { BetterList<UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition); if (widgets.size > 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); mStartPos = t.position; NGUIEditorTools.RegisterUndo("Move panel", t); } else if (mActionUnderMouse == UIWidgetInspector.Action.Rotate) { mStartRot = t.localRotation.eulerAngles; mStartDir = mStartDrag - t.position; NGUIEditorTools.RegisterUndo("Rotate panel", t); } else if (mActionUnderMouse == UIWidgetInspector.Action.Scale) { mStartPos = t.localPosition; mStartCR = mPanel.clipRange; mDragPivot = pivotUnderMouse; NGUIEditorTools.RegisterUndo("Scale panel", t); NGUIEditorTools.RegisterUndo("Scale panel", mPanel); } mAction = actionUnderMouse; } } if (mAction != UIWidgetInspector.Action.None) { if (mAction == UIWidgetInspector.Action.Move) { t.position = mStartPos + (pos - mStartDrag); t.localPosition = NGUISnap.Snap(t.localPosition, mPanel.localCorners, e.modifiers != EventModifiers.Control); } 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, mStartPos, mStartCR, delta, mDragPivot); } } } } } } 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 (mAction != UIWidgetInspector.Action.None) { if (mAction == UIWidgetInspector.Action.Move) { t.position = mStartPos; } else if (mAction == UIWidgetInspector.Action.Rotate) { t.localRotation = Quaternion.Euler(mStartRot); } else if (mAction == UIWidgetInspector.Action.Scale) { t.position = mStartPos; mPanel.clipRange = mStartCR; } } GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; mActionUnderMouse = UIWidgetInspector.Action.None; mAction = UIWidgetInspector.Action.None; e.Use(); } else Selection.activeGameObject = null; } } break; } }
/// <summary> /// Handles & interaction. /// </summary> public void OnSceneGUI() { 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) { BetterList <UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition); if (widgets.size > 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; } }
/// <summary> /// Handles & interaction. /// </summary> public void OnSceneGUI() { 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; bool canResize = (mPanel.clipping != UIDrawCall.Clipping.None); UIWidget.Pivot pivotUnderMouse = UIWidgetInspector.GetPivotUnderMouse(handles, e, canResize, ref actionUnderMouse); Handles.color = new Color(0.5f, 0f, 0.5f); Handles.DrawLine(handles[0], handles[1]); Handles.DrawLine(handles[1], handles[2]); Handles.DrawLine(handles[2], handles[3]); Handles.DrawLine(handles[0], handles[3]); switch (type) { case EventType.Repaint: { Vector3 bottomLeft = HandleUtility.WorldToGUIPoint(handles[0]); Vector3 topRight = HandleUtility.WorldToGUIPoint(handles[2]); Vector3 diff = topRight - bottomLeft; float mag = diff.magnitude; if (mag > 140f) { Handles.BeginGUI(); for (int i = 0; i < 8; ++i) { DrawKnob(handles[i], id); } Handles.EndGUI(); } else if (mag > 40f) { Handles.BeginGUI(); for (int i = 0; i < 4; ++i) { DrawKnob(handles[i], id); } Handles.EndGUI(); } } break; case EventType.MouseDown: { 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)) { mStartPos = t.position; mStartRot = t.localRotation.eulerAngles; mStartDir = mStartDrag - t.position; mStartCR = mPanel.clipRange; 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) { BetterList <UIWidget> widgets = NGUIEditorTools.SceneViewRaycast(e.mousePosition); if (widgets.size > 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); mStartPos = t.position; NGUIEditorTools.RegisterUndo("Move panel", t); } else if (mActionUnderMouse == UIWidgetInspector.Action.Rotate) { mStartRot = t.localRotation.eulerAngles; mStartDir = mStartDrag - t.position; NGUIEditorTools.RegisterUndo("Rotate panel", t); } else if (mActionUnderMouse == UIWidgetInspector.Action.Scale) { mStartPos = t.localPosition; mStartCR = mPanel.clipRange; mDragPivot = pivotUnderMouse; NGUIEditorTools.RegisterUndo("Scale panel", t); NGUIEditorTools.RegisterUndo("Scale panel", mPanel); } mAction = actionUnderMouse; } } if (mAction != UIWidgetInspector.Action.None) { if (mAction == UIWidgetInspector.Action.Move) { t.position = mStartPos + (pos - mStartDrag); t.localPosition = NGUISnap.Snap(t.localPosition, mPanel.localCorners, e.modifiers != EventModifiers.Control); } 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, mStartPos, mStartCR, delta, mDragPivot); } } } } } } 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 (mAction != UIWidgetInspector.Action.None) { if (mAction == UIWidgetInspector.Action.Move) { t.position = mStartPos; } else if (mAction == UIWidgetInspector.Action.Rotate) { t.localRotation = Quaternion.Euler(mStartRot); } else if (mAction == UIWidgetInspector.Action.Scale) { t.position = mStartPos; mPanel.clipRange = mStartCR; } } GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; mActionUnderMouse = UIWidgetInspector.Action.None; mAction = UIWidgetInspector.Action.None; e.Use(); } else { Selection.activeGameObject = null; } } } break; } }