Quantcast
Channel: Resize Adorner`s thumb goes crazy
Viewing all articles
Browse latest Browse all 2

Resize Adorner`s thumb goes crazy

$
0
0

Hello All,

   I have developed a WPF application that permits the user to draw shapes like Rectangle, Ellipse, Line, and Polyline objects over DrawingSurface (canvas), also the user can zoom-in and zoom-out the DrawingSurface , which means zooming-in/out these shapes too. These shapes can be resized. For resizing I used adorners.

I iherited the Adorner class and made custom ResizeAdorner class. This class contains 8 thumbs (topLeft, top, topRight, left, right, bottomLeft, bottom ,bottomRight) who are placed at corners and sides of adorned item (selected shape).

Because, I didn`t want my thumbs to be scaled with shape that is currently editing, if the shape was scaled-up or down, therefore I overrided the GetDesiredTransform method in my adorner class (ResizeAdorner) to scale down the thumb by setting the Thumb.RenderTransform property to 1/zoomFactor.

This is the point where my problems starts.

If I try to resize the shape, the thub starts to behave strange. It`s drag delta gets strange values who are not desired and who affect on shape`s shape(size). If I let thumbs to scale with shape (I have big,  scaled thumbs) everything works fine.

I noticed that Canvas.SetTop(), CanvasSetLeft() method in MoveXXX mehtods in EllipseResizeAdorner class affect on this problem. Everything works fine on zoom level 1. (1:1) but when I increase/decrease zoom level problems starts.

What might be a problem ?

Thanks in advance.

Here is code of ResizeAdorner class:

	public abstract class ResizeAdorner : Adorner
	{
		#region Fields		
		public static readonly RoutedEvent MoveResizeAdornerThumbEvent = EventManager.RegisterRoutedEvent("MoveResizeAdornerThumb", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ResizeAdorner));

		// Represent Flag that indicates that mirrored axis is corssed during ellipse resizing process.
		private bool mirrorAxisYCrossed = false;
		private bool mirrorAxisXCrossed = false;		
		
		// Represent thumbs which surrounds DrawingItem and we use them for resizing the drawing item.
		private ResizeAdornerThumb resizeTopLeftThumb;
		private ResizeAdornerThumb resizeTopThumb;
		private ResizeAdornerThumb resizeTopRightThumb;
		private ResizeAdornerThumb resizeLeftThumb;
		private ResizeAdornerThumb resizeRightThumb;
		private ResizeAdornerThumb resizeBottomLeftThumb;
		private ResizeAdornerThumb resizeBottomThumb;
		private ResizeAdornerThumb resizeBottomRightThumb;

		// Represent Horisontal and Vertical start points of ResizeAdorner Thumbs during moving.
		private double thumbHorizontalStartPoint;
		private double thumbVerticalStartPoint;
		#endregion		

		private VisualCollection visualChildren;
		
		protected DrawingItem DrawingItem { get; set; }
		protected FrameworkElement ItemCanvas { get; set; }
		// Constructors
		public ResizeAdorner(FrameworkElement itemCanvas, DrawingItem drawingItem)
			: base(drawingItem)
		{
			this.DrawingItem = drawingItem;
			this.visualChildren = new VisualCollection(this);

			this.ItemCanvas = itemCanvas;

			InitializeResizeTopLeftThumb();
			InitializeResizeTopThumb();
			InitializeResizeTopRightThumb();
			InitializeResizeLeftThumb();
			InitializeResizeRightThumb();
			InitializeResizeBottomLeftThumb();
			InitializeResizeBottomThumb();
			InitializeResizeBottomRightThumb();

			
		}		

		public event RoutedEventHandler MoveResizeAdornerThumbHandler
		{
			add { AddHandler(MoveResizeAdornerThumbEvent, value); }
			remove { RemoveHandler(MoveResizeAdornerThumbEvent, value); }
		}

		#region Properties
		protected bool MirrorAxisYCrossed
		{
			get { return mirrorAxisYCrossed; }
			set { mirrorAxisYCrossed = value; }
		}

		protected bool MirrorAxisXCrossed
		{
			get { return mirrorAxisXCrossed; }
			set { mirrorAxisXCrossed = value; }
		}

		protected ResizeAdornerThumb ResizeTopLeftThumb
		{
			get { return resizeTopLeftThumb; }
			set { resizeTopLeftThumb = value; }
		}

		protected ResizeAdornerThumb ResizeTopThumb
		{
			get { return resizeTopThumb; }
			set { resizeTopThumb = value; }
		}

		protected ResizeAdornerThumb ResizeTopRightThumb
		{
			get { return resizeTopRightThumb; }
			set { resizeTopRightThumb = value; }
		}

		protected ResizeAdornerThumb ResizeLeftThumb
		{
			get { return resizeLeftThumb; }
			set { resizeLeftThumb = value; }
		}

		protected ResizeAdornerThumb ResizeRightThumb
		{
			get { return resizeRightThumb; }
			set { resizeRightThumb = value; }
		}

		protected ResizeAdornerThumb ResizeBottomLeftThumb
		{
			get { return resizeBottomLeftThumb; }
			set { resizeBottomLeftThumb = value; }
		}

		protected ResizeAdornerThumb ResizeBottomThumb
		{
			get { return resizeBottomThumb; }
			set { resizeBottomThumb = value; }
		}

		protected ResizeAdornerThumb ResizeBottomRightThumb
		{
			get { return resizeBottomRightThumb; }
			set { resizeBottomRightThumb = value; }
		}
		#endregion

		public  void ShowAdorner()
		{
			resizeTopLeftThumb.Visibility = Visibility.Visible;
			resizeTopThumb.Visibility = Visibility.Visible;
			resizeTopRightThumb.Visibility = Visibility.Visible;
			resizeLeftThumb.Visibility = Visibility.Visible;
			resizeRightThumb.Visibility = Visibility.Visible;
			resizeBottomLeftThumb.Visibility = Visibility.Visible;
			resizeBottomThumb.Visibility = Visibility.Visible;
			resizeBottomRightThumb.Visibility = Visibility.Visible;
		}

		public  void HideAdorner()
		{
			resizeTopLeftThumb.Visibility = Visibility.Hidden;
			resizeTopThumb.Visibility = Visibility.Hidden;
			resizeTopRightThumb.Visibility = Visibility.Hidden;
			resizeLeftThumb.Visibility = Visibility.Hidden;
			resizeRightThumb.Visibility = Visibility.Hidden;
			resizeBottomLeftThumb.Visibility = Visibility.Hidden;
			resizeBottomThumb.Visibility = Visibility.Hidden;
			resizeBottomRightThumb.Visibility = Visibility.Hidden;
		}

		public void RaiseMoveResizeAdornerThumbEvent(ResizeAdornerThumb thumb, double horizontalChange, double verticalChange, bool mirrorAxisXCrossed, bool mirrorAxisYCrossed)
		{
			MovedResizeAdornerThumbRoutedEventArgs newEventArgs = new MovedResizeAdornerThumbRoutedEventArgs(MoveResizeAdornerThumbEvent, 
																											 this, 
																											 thumb, 
																											 horizontalChange, 
																											 verticalChange, 
																											 mirrorAxisXCrossed, 
																											 mirrorAxisYCrossed);
			RaiseEvent(newEventArgs);
		}

		public void MoveResizeAdornerThumb(ResizeAdornerThumb thumb, double horizontalMove, double verticalMove, bool resetMirrorFlags)
		{
			ResizeAdornerThumb.ThumbType thumbType = thumb.Type;
			//CheckHelper.CheckCanvasBoundaries(this.ItemCanvas, thumb, ref horizontalMove, ref verticalMove);
			
			switch (thumbType)
			{
				case ResizeAdornerThumb.ThumbType.TopLeft:
					MoveTop(verticalMove);
					MoveLeft(horizontalMove);
					break;
				case ResizeAdornerThumb.ThumbType.Top:
					MoveTop(verticalMove);
					break;
				case ResizeAdornerThumb.ThumbType.TopRight:
					MoveTop(verticalMove);
					MoveRight(horizontalMove);
					break;
				case ResizeAdornerThumb.ThumbType.Left:
					MoveLeft(horizontalMove);
					break;
				case ResizeAdornerThumb.ThumbType.Right:
					MoveRight(horizontalMove);
					break;
				case ResizeAdornerThumb.ThumbType.BottomLeft:
					MoveBottom(verticalMove);
					MoveLeft(horizontalMove);
					break;
				case ResizeAdornerThumb.ThumbType.Bottom:
					MoveBottom(verticalMove);
					break;
				case ResizeAdornerThumb.ThumbType.BottomRight:
					MoveBottom(verticalMove);
					MoveRight(horizontalMove);
					break;
				default:
					break;
			}

			if (resetMirrorFlags)
			{
				// Reset mirror flags
				this.mirrorAxisXCrossed = false;
				this.mirrorAxisYCrossed = false;
			}
		}

		protected abstract void MoveTop(double verticalChange);
		protected abstract void MoveBottom(double verticalChange);
		protected abstract void MoveLeft(double horizontalChange);
		protected abstract void MoveRight(double horizontalChange);
	

		#region ResizeAdornerThumbs
		private void InitializeResizeTopLeftThumb()
		{
			resizeTopLeftThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.TopLeft, Cursors.SizeNWSE);

			resizeTopLeftThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeTopLeftThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeTopLeftThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeTopLeftThumb);
		}

		private void InitializeResizeTopThumb()
		{
			resizeTopThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.Top, Cursors.SizeNS);

			resizeTopThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeTopThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeTopThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeTopThumb);
		}
		
		private void InitializeResizeTopRightThumb()
		{
			this.resizeTopRightThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.TopRight, Cursors.SizeNESW);

			resizeTopRightThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeTopRightThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeTopRightThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeTopRightThumb);
		}
		
		private void InitializeResizeLeftThumb()
		{
			resizeLeftThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.Left, Cursors.SizeWE);

			resizeLeftThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeLeftThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeLeftThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeLeftThumb);
		}

		private void InitializeResizeRightThumb()
		{
			resizeRightThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.Right, Cursors.SizeWE);

			resizeRightThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeRightThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeRightThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeRightThumb);
		}

		private void InitializeResizeBottomLeftThumb()
		{
			resizeBottomLeftThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.BottomLeft, Cursors.SizeNESW);

			resizeBottomLeftThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeBottomLeftThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeBottomLeftThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeBottomLeftThumb);
		}
		
		private void InitializeResizeBottomThumb()
		{
			resizeBottomThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.Bottom, Cursors.SizeNS);

			resizeBottomThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeBottomThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeBottomThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeBottomThumb);
		}

		private void InitializeResizeBottomRightThumb()
		{
			resizeBottomRightThumb = new ResizeAdornerThumb(ResizeAdornerThumb.ThumbType.BottomRight, Cursors.SizeNWSE);

			resizeBottomRightThumb.DragStarted += new DragStartedEventHandler(ResizeAdornerThumb_DragStarted);
			resizeBottomRightThumb.DragCompleted += new DragCompletedEventHandler(ResizeAdornerThumb_DragCompleted);
			resizeBottomRightThumb.DragDelta += new DragDeltaEventHandler(ResizeAdornerThumb_DragDelta);

			this.visualChildren.Add(resizeBottomRightThumb);
		}
		#endregion

		// Resize Adorner Thumbs Handlers
		#region ResizeAdornerThumbs Handlers
		private void ResizeAdornerThumb_DragStarted(object sender, DragStartedEventArgs e)
		{
			ResizeAdornerThumb thumb = sender as ResizeAdornerThumb;
			thumbHorizontalStartPoint = Canvas.GetLeft(thumb);
			thumbVerticalStartPoint = Canvas.GetTop(thumb);
		}

		private void ResizeAdornerThumb_DragCompleted(object sender, DragCompletedEventArgs e)
		{
			//ResizeAdornerThumb thumb = sender as ResizeAdornerThumb;
			//double thumbHorizontalChange = 0;
			//double thumbVerticalChange = 0;

			//// Calculate appropriate horisontal change for certain thumb
			//if (mirrorAxisYCrossed)
			//{
			//    // For Left thumbs
			//    if (thumb.Type == ResizeAdornerThumb.ThumbType.TopLeft ||
			//        thumb.Type == ResizeAdornerThumb.ThumbType.Left ||
			//        thumb.Type == ResizeAdornerThumb.ThumbType.BottomLeft)
			//    {
			//        thumbHorizontalChange = (Canvas.GetLeft(thumb) - thumbHorizontalStartPoint) + this.DrawingItem.Width; // +width because we were crossed Y axis and at that point left thumb is fixed at Y axis
			//    }
			//    else
			//    {
			//        // For right thumbs
			//        thumbHorizontalChange = (thumbHorizontalStartPoint - Canvas.GetLeft(thumb)) + this.DrawingItem.Width;
			//        thumbHorizontalChange = -thumbHorizontalChange; // negative move
			//    }
			//}

			//else
			//{
			//    thumbHorizontalChange = Canvas.GetLeft(thumb) - thumbHorizontalStartPoint;
			//}

			//// Calculate appropriate vertical change for certain thumb
			//if (mirrorAxisXCrossed)
			//{
			//    // For Top thumbs
			//    if (thumb.Type == ResizeAdornerThumb.ThumbType.TopLeft ||
			//        thumb.Type == ResizeAdornerThumb.ThumbType.Top ||
			//        thumb.Type == ResizeAdornerThumb.ThumbType.TopRight)
			//    {
			//        thumbVerticalChange = (Canvas.GetTop(thumb) - thumbVerticalStartPoint) + this.DrawingItem.Height;
			//    }
			//    else
			//    {
			//        // For Bottom thumbs
			//        thumbVerticalChange = (thumbVerticalStartPoint - Canvas.GetTop(thumb)) + this.DrawingItem.Height;
			//        thumbVerticalChange = -thumbVerticalChange; // negative move
			//    }
			//}
			//else
			//{
			//    thumbVerticalChange = Canvas.GetTop(thumb) - thumbVerticalStartPoint;
			//}

			//this.RaiseMoveResizeAdornerThumbEvent(thumb, thumbHorizontalChange, thumbVerticalChange, mirrorAxisXCrossed, mirrorAxisYCrossed);

			// Reset mirror flags
			this.mirrorAxisXCrossed = false;
			this.mirrorAxisYCrossed = false;
		}

		private void ResizeAdornerThumb_DragDelta(object sender, DragDeltaEventArgs e)
		{
			ResizeAdornerThumb thumb = sender as ResizeAdornerThumb;
			MoveResizeAdornerThumb(thumb, e.HorizontalChange, e.VerticalChange, false);			
		}
		#endregion


		protected override int VisualChildrenCount
		{
			get
			{
				return this.visualChildren.Count;
			}
		}

		protected override Visual GetVisualChild(int index)
		{
			return this.visualChildren[index];
		}


		protected override Size ArrangeOverride(Size finalSize)
		{
			base.ArrangeOverride(finalSize);

			double thumbWidth = resizeTopLeftThumb.Width;
			double thumbHeight = resizeTopLeftThumb.Height;
			double desiredWidth = AdornedElement.DesiredSize.Width;
			double desiredHeight = AdornedElement.DesiredSize.Height;

			resizeTopLeftThumb.Arrange(new Rect(-thumbWidth / 2, -thumbHeight / 2, thumbWidth, thumbHeight));
			resizeTopThumb.Arrange(new Rect(desiredWidth / 2 - thumbWidth / 2, -thumbHeight / 2, thumbWidth, thumbHeight));
			resizeTopRightThumb.Arrange(new Rect(desiredWidth - thumbWidth / 2, -thumbHeight / 2, thumbWidth, thumbHeight));

			resizeLeftThumb.Arrange(new Rect(-thumbWidth / 2, desiredHeight/2 - thumbHeight / 2, thumbWidth, thumbHeight));
			resizeRightThumb.Arrange(new Rect(desiredWidth - thumbWidth / 2, desiredHeight/2 - thumbHeight / 2, thumbWidth, thumbHeight));

			resizeBottomLeftThumb.Arrange(new Rect(-thumbWidth / 2, desiredHeight - thumbHeight / 2, thumbWidth, thumbHeight));
			resizeBottomThumb.Arrange(new Rect(desiredWidth / 2 - thumbWidth / 2, desiredHeight - thumbHeight / 2, thumbWidth, thumbHeight));
			resizeBottomRightThumb.Arrange(new Rect(desiredWidth - thumbWidth / 2, desiredHeight - thumbHeight / 2, thumbWidth, thumbHeight));

			return finalSize;
		}

		public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
		{
			ZoomControl zc = GetParentZoomControl(this.DrawingItem);
			double zoomFactor = zc.Zoom;

			resizeTopLeftThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeTopLeftThumb.RenderTransformOrigin = new Point(0.5, 0.5);

			resizeTopThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeTopThumb.RenderTransformOrigin = new Point(0.5, 0.5);

			resizeTopRightThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeTopRightThumb.RenderTransformOrigin = new Point(0.5, 0.5);

			resizeLeftThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeLeftThumb.RenderTransformOrigin = new Point(0.5, 0.5);

			resizeRightThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeRightThumb.RenderTransformOrigin = new Point(0.5, 0.5);

			resizeBottomLeftThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeBottomLeftThumb.RenderTransformOrigin = new Point(0.5, 0.5);

			resizeBottomThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeBottomThumb.RenderTransformOrigin = new Point(0.5, 0.5);

			resizeBottomRightThumb.RenderTransform = new ScaleTransform(1 / zoomFactor, 1 / zoomFactor);
			resizeBottomRightThumb.RenderTransformOrigin = new Point(0.5, 0.5);


			return base.GetDesiredTransform(transform);
		}


		public ZoomControl GetParentZoomControl(Visual referenceVisual)
		{
			Visual parent = referenceVisual;
			while (parent != null)
			{
				parent = VisualTreeHelper.GetParent(parent) as Visual;
				if ((parent.GetType() == typeof(ZoomControl)))
				{
					return parent as ZoomControl;
				}
			}
			return parent as ZoomControl;
		}

		
	}
	public class EllipseResizeAdorner : ResizeAdorner
	{
		public EllipseResizeAdorner(FrameworkElement itemCanvas, DrawingItem drawingItem)
			: base(itemCanvas, drawingItem)
		{
		}

		protected override void MoveLeft(double horizontalMove)
		{
			// The Right of the Y-axis
			if (MirrorAxisYCrossed)
			{
				if (horizontalMove < 0)
				{
					// At this moment we were crossed Y-axis. Direction RIGHT-LEFT
					Canvas.SetLeft(DrawingItem, Canvas.GetLeft(DrawingItem) - DrawingItem.Width); // Neutralize drag delta
					MirrorAxisYCrossed = false; // Set corssing flag
				}
				else
				{
					// Still the right of the Y-axis
					DrawingItem.Width = horizontalMove; // Drag dleta depends on top of ellipse.
				}
			}
			else
			{
				// The Left of the Y-axis
				if (horizontalMove > DrawingItem.Width)
				{
					// At this moment we were crossed Y-axis. Direction LEFT-RIGHT; Drag dleta depends on Left side of ellipse.
					if (!MirrorAxisYCrossed)
					{
						// Crossing flag isn`t set yet.
						Canvas.SetLeft(DrawingItem, Canvas.GetLeft(DrawingItem) + DrawingItem.Width);  // Move top of ellipse on a appropriate distance
						horizontalMove = horizontalMove - DrawingItem.Width;             // Recalculate new horizontalMove for Y - axis mirrored ellipse
						DrawingItem.Width = horizontalMove;
					}

					MirrorAxisYCrossed = true;
				}
				else
				{
					// Still Left of the Y-axis
					DrawingItem.Width = DrawingItem.Width - horizontalMove;
					Canvas.SetLeft(DrawingItem, Canvas.GetLeft(DrawingItem) + horizontalMove);
				}
			}
		}

		protected override void MoveTop(double verticalMove)
		{
			if (MirrorAxisXCrossed)
			{
				// Below X-axis
				if (verticalMove < 0)
				{
					// At this moment we were crossed X-axis. Direction BOTTOM-TOP
					Canvas.SetTop(DrawingItem, Canvas.GetTop(DrawingItem) - DrawingItem.Height); // Neutralize drag delta
					MirrorAxisXCrossed = false; // Set corssing flag
				}
				else
				{
					// Still below X-Axis
					DrawingItem.Height = verticalMove; // Drag dleta depends on top of ellipse.
				}
			}
			else
			{
				FrameworkElement adornedElement = DrawingItem as FrameworkElement;
				EnforceSize(adornedElement);
				// Above X-axis
				if (verticalMove > DrawingItem.Height)
				{
					// At this moment we were crossed X-axis. Direction TOP-BOTTOM; Drag dleta depends on top of ellipse.
					if (!MirrorAxisXCrossed)
					{
						// Crossing flag isn`t set yet.
						Canvas.SetTop(DrawingItem, Canvas.GetTop(DrawingItem) + DrawingItem.Height);  // Move top of ellipse on a appropriate distance
						EnforceSize(adornedElement);
						verticalMove = verticalMove - DrawingItem.Height;               // Recalculate new verticalMove for X - axis mirrored ellipse
						DrawingItem.Height = verticalMove;
					}

					MirrorAxisXCrossed = true;
				}
				else
				{
					// Still above X-Axis 
					DrawingItem.Height = DrawingItem.Height - verticalMove;
					Canvas.SetTop(DrawingItem, Canvas.GetTop(DrawingItem) + verticalMove);
				}
			}
		}

		protected override void MoveRight(double horizontalMove)
		{
			if (MirrorAxisYCrossed)
			{
				// The Left of the Y-axis
				if (horizontalMove <= 0)
				{
					Canvas.SetLeft(DrawingItem, Canvas.GetLeft(DrawingItem) + DrawingItem.Width + horizontalMove);
					DrawingItem.Width = (-horizontalMove);
				}
				else
				{
					// We were crossed Y-axis. Direction LEFT-RIGHT; ActualMove = horizontalMove + Ellipse.Width
					Canvas.SetLeft(DrawingItem, Canvas.GetLeft(DrawingItem) + DrawingItem.Width);

					DrawingItem.Width = horizontalMove;
					MirrorAxisYCrossed = false;
				}
			}
			else
			{
				// The Right of the Y-axis
				if ((-horizontalMove) > DrawingItem.Width)
				{
					// At this moment we were crossed Y-axis. Direction RIGHT-LEFT; Drag dleta depends on Left side of ellipse.
					double delta = -horizontalMove - DrawingItem.Width;
					Canvas.SetLeft(DrawingItem, Canvas.GetLeft(DrawingItem) - delta);
					DrawingItem.Width = delta;
					MirrorAxisYCrossed = true;
				}
				else
				{
					// Still Right of the Y-axis
					DrawingItem.Width = DrawingItem.Width + horizontalMove;
				}
			}
		}

		protected override void MoveBottom(double verticalMove)
		{
			if (MirrorAxisXCrossed)
			{
				// Above X-axis
				// VerticalMove gorws proportionally becaouse Canvas.SetTop() method repaint ellipse 
				// so the bottomThomb location is allways on the X-axis(bootom od ellipse).As we drag up, the delta grows propotionally. 
				if (verticalMove <= 0)
				{
					Canvas.SetTop(DrawingItem, Canvas.GetTop(DrawingItem) + DrawingItem.Height + verticalMove);
					DrawingItem.Height = (-verticalMove);
				}
				else
				{
					// We were crossed X-axis. Direction TOP-BOTTOM; ActualMove = verticalMove + Ellipse.Heihgt
					Canvas.SetTop(DrawingItem, Canvas.GetTop(DrawingItem) + DrawingItem.Height);
					DrawingItem.Height = verticalMove;
					MirrorAxisXCrossed = false;
				}
			}
			else
			{
				// Below X-axis 
				// Because of fixed top of ellipse and changeable Height, verticalMove delta(step) is 1;
				if (-verticalMove > DrawingItem.Height)
				{
					// At this moment we have been crossed X-axis. Direction BOTTOM-TOP; 
					double delta = -verticalMove - DrawingItem.Height;
					Canvas.SetTop(DrawingItem, Canvas.GetTop(DrawingItem) - delta);
					DrawingItem.Height = delta;
					MirrorAxisXCrossed = true;
				}
				else
				{
					// Still below X-Axis
					DrawingItem.Height = DrawingItem.Height + verticalMove;
				}
			}
		}

Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images