// User clicked the map. // Remember that mouse position for later use // when calculating map drag offset private void MapControl_MouseDown(object sender, MouseEventArgs e) { MapToken tokenUnderMouse = getTokenUnderMouse(e.Location); mouseDownPos = e.Location; mouseDownTimer.Reset(); mouseDownTimer.Start(); if (e.Button == MouseButtons.Left) { leftMouseDown = true; if (tokenUnderMouse != null) { tokenUnderMouse.MouseState = TokenMouseState.Drag; this.draggedToken = tokenUnderMouse; this.mouseDragState = MouseDragState.Token; } else { this.mouseDragState = MouseDragState.Map; } } else if (e.Button == MouseButtons.Right) { if (tokenUnderMouse != null) { rightClickedToken = tokenUnderMouse; tokenContextMenu.Show(this, e.Location); } else { rightClickedToken = null; mapContextMenu.Show(this, e.Location); } } refreshIfNeeded(); }
/// <summary> /// Gets called when an interaction with the right mouse button has been made. /// </summary> /// <param name="mousePos"></param> protected override void OnRightMouseButtonEvent(Vector2 mousePos) { if (this.Context.IsPlayMode || this.Context.IsPrefabAsset) { return; } var node = Context.Graph.GetClickedNode(this, mousePos); //Has a state been clicked? if (node != null) { ICommand command = null; switch (Event.current.type) { //Select clicked state case EventType.MouseDown: command = new SelectClickedStateCommand(Context, node); break; //Show context menu for selected state case EventType.MouseUp: this.dragState = MouseDragState.None; command = new ShowContextMenuCommand(Context, node); break; } command?.Execute(); } }
internal MouseDragState(MouseDragState lastState, Point position) : this(lastState.start, lastState.position, position) { }
internal MouseButtonInfo(MouseButtonState state, MouseDragState dragState) { this.dragState = dragState; this.state = state; }
public override void OnSceneGUI() { base.OnSceneGUI(); LatticeDeformer lattice = target as LatticeDeformer; Transform transform = lattice.transform; float3[] controlPoints = lattice.ControlPoints; Event e = Event.current; using (new Handles.DrawingScope(transform.localToWorldMatrix)) { var cachedZTest = Handles.zTest; // Change the depth testing to only show handles in front of solid objects (i.e. typical depth testing) Handles.zTest = CompareFunction.LessEqual; DrawLattice(lattice, DeformHandles.LineMode.Solid); // Change the depth testing to only show handles *behind* solid objects Handles.zTest = CompareFunction.Greater; DrawLattice(lattice, DeformHandles.LineMode.Light); // Restore the original z test value now we're done with our drawing Handles.zTest = cachedZTest; var resolution = lattice.Resolution; for (int z = 0; z < resolution.z; z++) { for (int y = 0; y < resolution.y; y++) { for (int x = 0; x < resolution.x; x++) { var controlPointHandleID = GUIUtility.GetControlID("LatticeDeformerControlPoint".GetHashCode(), FocusType.Passive); var activeColor = DeformEditorSettings.SolidHandleColor; var controlPointIndex = lattice.GetIndex(x, y, z); if (GUIUtility.hotControl == controlPointHandleID || selectedIndices.Contains(controlPointIndex)) { activeColor = Handles.selectedColor; } else if (HandleUtility.nearestControl == controlPointHandleID) { activeColor = Handles.preselectionColor; } if (e.type == EventType.MouseDown && HandleUtility.nearestControl == controlPointHandleID && e.button == 0 && MouseActionAllowed) { BeginSelectionChangeRegion(); GUIUtility.hotControl = controlPointHandleID; GUIUtility.keyboardControl = controlPointHandleID; e.Use(); bool modifierKeyPressed = e.control || e.shift || e.command; if (modifierKeyPressed && selectedIndices.Contains(controlPointIndex)) { // Pressed a modifier key so toggle the selection selectedIndices.Remove(controlPointIndex); } else { if (!modifierKeyPressed) { selectedIndices.Clear(); } if (!selectedIndices.Contains(controlPointIndex)) { selectedIndices.Add(controlPointIndex); } } EndSelectionChangeRegion(); } if (Tools.current != Tool.None && selectedIndices.Count != 0) { // If the user changes tool, change our internal mode to match but disable the corresponding Unity tool // (e.g. they hit W key or press on the Rotate Tool button on the top left toolbar) activeTool = Tools.current; Tools.current = Tool.None; } using (new Handles.DrawingScope(activeColor)) { var position = controlPoints[controlPointIndex]; var size = HandleUtility.GetHandleSize(position) * DeformEditorSettings.ScreenspaceLatticeHandleCapSize; Handles.DotHandleCap( controlPointHandleID, position, Quaternion.identity, size, e.type); } } } } } var defaultControl = DeformUnityObjectSelection.DisableSceneViewObjectSelection(); if (selectedIndices.Count != 0) { var currentPivotPosition = float3.zero; if (Tools.pivotMode == PivotMode.Center) { // Get the average position foreach (var index in selectedIndices) { currentPivotPosition += controlPoints[index]; } currentPivotPosition /= selectedIndices.Count; } else { // Match the scene view behaviour that Pivot mode uses the last selected object as pivot currentPivotPosition = controlPoints[selectedIndices.Last()]; } float3 handlePosition = transform.TransformPoint(currentPivotPosition); if (e.type == EventType.MouseDown) { // Potentially started interacting with a handle so reset everything handleScale = Vector3.one; // Make sure we cache the positions just before the interaction changes them CacheOriginalPositions(); } var originalPivotPosition = float3.zero; if (Tools.pivotMode == PivotMode.Center) { // Get the average position foreach (var originalPosition in selectedOriginalPositions) { originalPivotPosition += originalPosition; } originalPivotPosition /= selectedIndices.Count; } else { // Match the scene view behaviour that Pivot mode uses the last selected object as pivot originalPivotPosition = selectedOriginalPositions.Last(); } var handleRotation = transform.rotation; if (Tools.pivotRotation == PivotRotation.Global) { handleRotation = Quaternion.identity; } if (activeTool == Tool.Move) { EditorGUI.BeginChangeCheck(); float3 newPosition = Handles.PositionHandle(handlePosition, handleRotation); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Update Lattice"); var delta = newPosition - handlePosition; delta = transform.InverseTransformVector(delta); foreach (var selectedIndex in selectedIndices) { controlPoints[selectedIndex] += delta; } CacheResizePositionsFromChange(); } } else if (activeTool == Tool.Rotate) { EditorGUI.BeginChangeCheck(); quaternion newRotation = Handles.RotationHandle(handleRotation, handlePosition); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Update Lattice"); for (var index = 0; index < selectedIndices.Count; index++) { if (Tools.pivotRotation == PivotRotation.Global) { controlPoints[selectedIndices[index]] = originalPivotPosition + (float3)transform.InverseTransformDirection(mul(newRotation, transform.TransformDirection(selectedOriginalPositions[index] - originalPivotPosition))); } else { controlPoints[selectedIndices[index]] = originalPivotPosition + mul(mul(inverse(handleRotation), newRotation), (selectedOriginalPositions[index] - originalPivotPosition)); } } CacheResizePositionsFromChange(); } } else if (activeTool == Tool.Scale) { var size = HandleUtility.GetHandleSize(handlePosition); EditorGUI.BeginChangeCheck(); handleScale = Handles.ScaleHandle(handleScale, handlePosition, handleRotation, size); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Update Lattice"); for (var index = 0; index < selectedIndices.Count; index++) { if (Tools.pivotRotation == PivotRotation.Global) { controlPoints[selectedIndices[index]] = originalPivotPosition + (float3)transform.InverseTransformDirection(handleScale * transform.TransformDirection(selectedOriginalPositions[index] - originalPivotPosition)); } else { controlPoints[selectedIndices[index]] = originalPivotPosition + handleScale * (selectedOriginalPositions[index] - originalPivotPosition); } } CacheResizePositionsFromChange(); } } Handles.BeginGUI(); if (GUI.Button(new Rect((EditorGUIUtility.currentViewWidth - 200) / 2, SceneView.currentDrawingSceneView.position.height - 60, 200, 30), Content.StopEditing)) { DeselectAll(); } Handles.EndGUI(); } if (e.button == 0) // Left Mouse Button { if (e.type == EventType.MouseDown && HandleUtility.nearestControl == defaultControl && MouseActionAllowed) { mouseDownPosition = e.mousePosition; mouseDragState = MouseDragState.Eligible; } else if (e.type == EventType.MouseDrag && mouseDragState == MouseDragState.Eligible) { mouseDragState = MouseDragState.InProgress; SceneView.currentDrawingSceneView.Repaint(); } else if (GUIUtility.hotControl == 0 && (e.type == EventType.MouseUp || (mouseDragState == MouseDragState.InProgress && e.rawType == EventType.MouseUp))) // Have they released the mouse outside the scene view while doing marquee select? { if (mouseDragState == MouseDragState.InProgress) { var mouseUpPosition = e.mousePosition; Rect marqueeRect = Rect.MinMaxRect(Mathf.Min(mouseDownPosition.x, mouseUpPosition.x), Mathf.Min(mouseDownPosition.y, mouseUpPosition.y), Mathf.Max(mouseDownPosition.x, mouseUpPosition.x), Mathf.Max(mouseDownPosition.y, mouseUpPosition.y)); BeginSelectionChangeRegion(); if (!e.shift && !e.control && !e.command) { selectedIndices.Clear(); } for (var index = 0; index < controlPoints.Length; index++) { Camera camera = SceneView.currentDrawingSceneView.camera; var screenPoint = DeformEditorGUIUtility.WorldToGUIPoint(camera, transform.TransformPoint(controlPoints[index])); if (screenPoint.z < 0) { // Don't consider points that are behind the camera continue; } if (marqueeRect.Contains(screenPoint)) { if (e.control || e.command) // Remove selection { selectedIndices.Remove(index); } else { selectedIndices.Add(index); } } } EndSelectionChangeRegion(); } else { if (selectedIndices.Count == 0) // This shouldn't be called if you have any points selected (we want to allow you to deselect the points) { DeformUnityObjectSelection.AttemptMouseUpObjectSelection(); } else { DeselectAll(); } } mouseDragState = MouseDragState.NotActive; } } if (e.type == EventType.Repaint && mouseDragState == MouseDragState.InProgress) { var mouseUpPosition = e.mousePosition; Rect marqueeRect = Rect.MinMaxRect(Mathf.Min(mouseDownPosition.x, mouseUpPosition.x), Mathf.Min(mouseDownPosition.y, mouseUpPosition.y), Mathf.Max(mouseDownPosition.x, mouseUpPosition.x), Mathf.Max(mouseDownPosition.y, mouseUpPosition.y)); DeformUnityObjectSelection.DrawUnityStyleMarquee(marqueeRect); SceneView.RepaintAll(); } // If the lattice is visible, override Unity's built-in Select All so that it selects all control points if (DeformUnityObjectSelection.SelectAllPressed) { BeginSelectionChangeRegion(); selectedIndices.Clear(); var resolution = lattice.Resolution; for (int z = 0; z < resolution.z; z++) { for (int y = 0; y < resolution.y; y++) { for (int x = 0; x < resolution.x; x++) { var controlPointIndex = lattice.GetIndex(x, y, z); selectedIndices.Add(controlPointIndex); } } } EndSelectionChangeRegion(); e.Use(); } if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Escape) { DeselectAll(); } EditorApplication.QueuePlayerLoopUpdate(); }
/// <summary> /// Gets there is an event on the left mouse button /// </summary> /// <param name="mousePos"></param> protected override void OnLeftMouseButtonEvent(Vector2 mousePos) { switch (Event.current.type) { //Only down events are relevant here case EventType.MouseDown: { this.dragState = MouseDragState.None; var node = Context.Graph.GetClickedNode(this, mousePos); //Has a state been clicked? if (node != null) { //Is the clicked state the target of a new transition? if (EditorApplication.isPlaying == false && this.Context.TransitionPreview != null && this.Context.TransitionPreview != node) { //Only states can be a target of a transition if (node is State state) { this.Context.StateMachine.AddTransition(this.Context.TransitionPreview, state); this.Context.TransitionPreview = null; } } //Ctrl Pressed? Add/Remove State from selection else if (EditorApplication.isPlaying == false && Event.current.control) { if (this.Context.SelectedNodes.Count > 0) { Selection.activeObject = null; } if (this.Context.SelectedNodes.Contains(node)) { this.Context.SelectedNodes.Remove(node); } else { this.Context.SelectedNodes.Add(node); } } //Otherwise just select this state else { if (this.Context.SelectedNodes.Count < 2 || !this.Context.SelectedNodes.Contains(node)) { this.Context.SelectedNodes.Clear(); this.Context.SelectedNodes.Add(node); //Selection.activeObject = state; if (node is State state) { StateInspectorHelper.Instance.Inspect(this.Context.StateMachine, this.Context.Graph, state); } else { if (Selection.activeObject == StateInspectorHelper.Instance) { Selection.activeObject = null; } } } } Event.current.Use(); } break; } case EventType.MouseDrag: { if (this.Context.IsPlayMode || this.Context.IsPrefabAsset) { break; } if (!Event.current.control) { if (this.dragState == MouseDragState.None) { Undo.RegisterCompleteObjectUndo(this.Context.StateMachine, "Dragged state"); this.dragState = MouseDragState.OnDrag; } else { if (this.Context.SelectedNodes.Count > 0) { Event.current.Use(); GUI.changed = true; } foreach (Node node in this.Context.SelectedNodes) { Rect rect = node.Rect; rect.x += Event.current.delta.x / this.Context.ZoomFactor; rect.y += Event.current.delta.y / this.Context.ZoomFactor; node.Rect = rect; } } } break; } case EventType.MouseUp: if (this.dragState == MouseDragState.OnDrag) { this.dragState = MouseDragState.None; } break; } }