/// <summary> /// Determines one component of a UIElement's location /// within a Canvas (horizontal or vertical offset) /// and according to it reletive to which sides it may be relocated /// </summary> /// <param name="Left"> /// The value of an offset relative to a Left side of the Canvas /// </param> /// <param name="Right"> /// The value of the offset relative to the Right side of the Canvas /// </param> /// <param name="Top"> /// The value of an offset relative to a Top side of the Canvas /// </param> /// <param name="Bottom"> /// The value of the offset relative to the Bottom side of the Canvas /// </param> private ModificationDirection ResolveOffset(double Left, double Right, double Top, double Bottom) { // If the Canvas.Left and Canvas.Right attached properties // are specified for an element, the 'Left' value is honored. // The 'Top' value is honored if both Canvas.Top and // Canvas.Bottom are set on the same element. If one // of those attached properties is not set on an element, // the default value is Double.NaN. m_OriginalLefOffset = Left; m_OriginalRightOffset = Right; m_OriginalTopOffset = Top; m_OriginalBottomOffset = Bottom; ModificationDirection result = ModificationDirection.None; if (!Double.IsNaN(m_OriginalLefOffset)) { result |= ModificationDirection.Left; } if (!Double.IsNaN(m_OriginalRightOffset)) { result |= ModificationDirection.Right; } if (!Double.IsNaN(m_OriginalTopOffset)) { result |= ModificationDirection.Top; } if (!Double.IsNaN(m_OriginalBottomOffset)) { result |= ModificationDirection.Bottom; } return(result); }
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnPreviewMouseLeftButtonDown(e); // call the handler of the base first m_IsDragInProgress = false; m_InitialCursorLocation = e.GetPosition(this); // Cache the mouse cursor location //check if the mouse was clicked on the ScrollBar, in which case let the ScrollBar remain its control. if (null != GetParentOfType <ScrollBar>(e.OriginalSource as DependencyObject)) { return; } // Walk up the visual tree from the element that was clicked, // looking for an element that is a direct child of the Canvas DraggedElement = FindCanvasChild(e.Source as DependencyObject); if (m_DraggedElement == null) { return; } m_ModificationDirection = ResolveOffset(Canvas.GetLeft(m_DraggedElement), Canvas.GetRight(m_DraggedElement), Canvas.GetTop(m_DraggedElement), Canvas.GetBottom(m_DraggedElement)); // Set the Handled flag so that a control being dragged // does not react to the mouse input e.Handled = true; if (m_ModificationDirection == ModificationDirection.None) { DraggedElement = null; return; } BringToFront(m_DraggedElement as UIElement); m_IsDragInProgress = true; }
public void Update(List<DummyObject> selectedObjects, Viewport viewport) { if (mControls.LeftPressed.Active) { Rectangle mousePixelRectangle = new Rectangle(mControls.MouseState.X, mControls.MouseState.Y, 1, 1); List<uint> objectIDs = GraphicsManager.GetPickingScreenObjects(mousePixelRectangle); uint mousePixel = objectIDs.Count > 0 ? objectIDs[0] : 0; if (mousePixel == mXPickingID || mousePixel == mYPickingID || mousePixel == mZPickingID) { mDragMode = Mode; IsDragging = true; } else { IsDragging = false; } switch (mousePixel) { case mXPickingID: mDragDirection = ModificationDirection.X; break; case mYPickingID: mDragDirection = ModificationDirection.Y; break; case mZPickingID: mDragDirection = ModificationDirection.Z; break; } mStartDragPoint = GetMouseWorldPosition(viewport); mPreviousDragPoint = mStartDragPoint; } else if (mControls.LeftReleased.Active) { IsDragging = false; } if (IsDragging) { Vector3 newDragPoint = GetMouseWorldPosition(viewport); switch (mDragMode) { case ModificationMode.TRANSLATE: foreach (DummyObject dummyObject in selectedObjects) { dummyObject.Position += (newDragPoint - mPreviousDragPoint) * GetDragDirection(); } break; case ModificationMode.SCALE: float scaleMultiplier = (newDragPoint - Position).Length() / (mPreviousDragPoint - Position).Length(); foreach (DummyObject dummyObject in selectedObjects) { Vector3 scale = scaleMultiplier * GetDragDirection() + (Vector3.One - GetDragDirection()); dummyObject.ApplyScale(scale); } break; case ModificationMode.ROTATE: Vector3 axis = GetDragDirection(); Vector3 newDirection = Vector3.Normalize(newDragPoint - Position); Vector3 previousDirection = Vector3.Normalize(mPreviousDragPoint - Position); float dot = Math.Min(1.0f, Math.Max(-1.0f, Vector3.Dot(newDirection, previousDirection))); float angle = (float)Math.Acos(dot); angle *= Vector3.Dot(Vector3.Cross(newDirection, previousDirection), axis) < 0.0f ? 1.0f : -1.0f; foreach (DummyObject dummyObject in selectedObjects) { Vector3 deltaYawPitchRoll = axis * angle; dummyObject.ApplyRotation(deltaYawPitchRoll, Position); } break; } mPreviousDragPoint = newDragPoint; } Position = Vector3.Zero; foreach (DummyObject dummyObject in selectedObjects) { Position += dummyObject.Position; } if (selectedObjects.Count > 0) { mDrawable = true; Position /= selectedObjects.Count; } else { mDrawable = false; } }