| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.Globalization;
 
- using System.Text;
 
- using Avalonia;
 
- using Avalonia.Controls;
 
- using Avalonia.Media;
 
- using Avalonia.Input;
 
- using Avalonia.Threading;
 
- using Avalonia.Controls.Shapes;
 
- namespace ControlCatalog.Pages
 
- {
 
-     public class CustomDrawingExampleControl : Control
 
-     {
 
-         private Point _cursorPoint;
 
-         public static readonly StyledProperty<double> ScaleProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Scale), 1.0d);
 
-         public double Scale { get => GetValue(ScaleProperty); set => SetValue(ScaleProperty, value); }
 
-         public static readonly StyledProperty<double> RotationProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(Rotation));
 
-         /// <summary>
 
-         /// Rotation, measured in Radians!
 
-         /// </summary>
 
-         public double Rotation
 
-         {
 
-             get => GetValue(RotationProperty);
 
-             set
 
-             {
 
-                 double valueToUse = value % (Math.PI * 2);
 
-                 SetValue(RotationProperty, valueToUse);
 
-             }
 
-         }
 
-         public static readonly StyledProperty<double> ViewportCenterYProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterY), 0.0d);
 
-         public double ViewportCenterY { get => GetValue(ViewportCenterYProperty); set => SetValue(ViewportCenterYProperty, value); }
 
-         public static readonly StyledProperty<double> ViewportCenterXProperty = AvaloniaProperty.Register<CustomDrawingExampleControl, double>(nameof(ViewportCenterX), 0.0d);
 
-         public double ViewportCenterX { get => GetValue(ViewportCenterXProperty); set => SetValue(ViewportCenterXProperty, value); }
 
-         private IPen _pen;
 
-         private System.Diagnostics.Stopwatch _timeKeeper = System.Diagnostics.Stopwatch.StartNew();
 
-         private bool _isPointerCaptured = false;
 
-         public CustomDrawingExampleControl()
 
-         {
 
-             _pen = new Pen(new SolidColorBrush(Colors.Black), lineCap: PenLineCap.Round);
 
-             var _arc = new ArcSegment()
 
-             {
 
-                 IsLargeArc = false,
 
-                 Point = new Point(0, 0),
 
-                 RotationAngle = 0,
 
-                 Size = new Size(25, 25),
 
-                 SweepDirection = SweepDirection.Clockwise,
 
-             };
 
-             StreamGeometry sg = new StreamGeometry();
 
-             using (var cntx = sg.Open())
 
-             {
 
-                 cntx.BeginFigure(new Point(-25.0d, -10.0d), false);
 
-                 cntx.ArcTo(new Point(25.0d, -10.0d), new Size(10.0d, 10.0d), 0.0d, false, SweepDirection.Clockwise);
 
-                 cntx.EndFigure(true);
 
-             }
 
-             _smileGeometry = sg.Clone();
 
-         }
 
-         private Geometry _smileGeometry;
 
-         protected override void OnPointerMoved(PointerEventArgs e)
 
-         {
 
-             base.OnPointerMoved(e);
 
-             Point previousPoint = _cursorPoint;
 
-             _cursorPoint = e.GetPosition(this);
 
-             if (_isPointerCaptured)
 
-             {
 
-                 Point oldWorldPoint = UIPointToWorldPoint(previousPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
 
-                 Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
 
-                 Vector diff = newWorldPoint - oldWorldPoint;
 
-                 ViewportCenterX -= diff.X;
 
-                 ViewportCenterY -= diff.Y;
 
-             }
 
-         }
 
-         protected override void OnPointerPressed(PointerPressedEventArgs e)
 
-         {
 
-             e.Handled = true;
 
-             e.Pointer.Capture(this);
 
-             _isPointerCaptured = true;
 
-             base.OnPointerPressed(e);
 
-         }
 
-         protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
 
-         {
 
-             base.OnPointerWheelChanged(e);
 
-             var oldScale = Scale;
 
-             Scale *= (1.0d + e.Delta.Y / 12.0d);
 
-             Point oldWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, oldScale, Rotation);
 
-             Point newWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
 
-             Vector diff = newWorldPoint - oldWorldPoint;
 
-             ViewportCenterX -= diff.X;
 
-             ViewportCenterY -= diff.Y;
 
-         }
 
-         protected override void OnPointerReleased(PointerReleasedEventArgs e)
 
-         {
 
-             e.Pointer.Capture(null);
 
-             _isPointerCaptured = false;
 
-             base.OnPointerReleased(e);
 
-         }
 
-         public override void Render(DrawingContext context)
 
-         {
 
-             var localBounds = new Rect(new Size(this.Bounds.Width, this.Bounds.Height));
 
-             var clip = context.PushClip(this.Bounds);
 
-             context.DrawRectangle(Brushes.White, _pen, localBounds, 1.0d);
 
-             var halfMax = Math.Max(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) * Math.Sqrt(2.0d);
 
-             var halfMin = Math.Min(this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d) / 1.3d;
 
-             var halfWidth = this.Bounds.Width / 2.0d;
 
-             var halfHeight = this.Bounds.Height / 2.0d;
 
-             // 0,0 refers to the top-left of the control now. It is not prime time to draw gui stuff because it'll be under the world 
 
-             var translateModifier = context.PushPreTransform(Avalonia.Matrix.CreateTranslation(new Avalonia.Vector(halfWidth, halfHeight)));
 
-             // now 0,0 refers to the ViewportCenter(X,Y). 
 
-             var rotationMatrix = Avalonia.Matrix.CreateRotation(Rotation);
 
-             var rotationModifier = context.PushPreTransform(rotationMatrix);
 
-             // everything is rotated but not scaled 
 
-             var scaleModifier = context.PushPreTransform(Avalonia.Matrix.CreateScale(Scale, -Scale));
 
-             var mapPositionModifier = context.PushPreTransform(Matrix.CreateTranslation(new Vector(-ViewportCenterX, -ViewportCenterY)));
 
-             // now everything is rotated and scaled, and at the right position, now we're drawing strictly in world coordinates
 
-             context.DrawEllipse(Brushes.White, _pen, new Point(0.0d, 0.0d), 50.0d, 50.0d);
 
-             context.DrawLine(_pen, new Point(-25.0d, -5.0d), new Point(-25.0d, 15.0d));
 
-             context.DrawLine(_pen, new Point(25.0d, -5.0d), new Point(25.0d, 15.0d));
 
-             context.DrawGeometry(null, _pen, _smileGeometry);
 
-             Point cursorInWorldPoint = UIPointToWorldPoint(_cursorPoint, ViewportCenterX, ViewportCenterY, Scale, Rotation);
 
-             context.DrawEllipse(Brushes.Gray, _pen, cursorInWorldPoint, 20.0d, 20.0d);
 
-             
 
-             for (int i = 0; i < 10; i++)
 
-             {
 
-                 double orbitRadius = i * 100 + 200;
 
-                 var orbitInput = ((_timeKeeper.Elapsed.TotalMilliseconds + 987654d) / orbitRadius) / 10.0d;
 
-                 if (i % 3 == 0)
 
-                     orbitInput *= -1;
 
-                 Point orbitPosition = new Point(Math.Sin(orbitInput) * orbitRadius, Math.Cos(orbitInput) * orbitRadius);
 
-                 context.DrawEllipse(Brushes.Gray, _pen, orbitPosition, 20.0d, 20.0d);
 
-             }
 
-             // end drawing the world 
 
-             mapPositionModifier.Dispose();
 
-             scaleModifier.Dispose();
 
-             rotationModifier.Dispose();
 
-             translateModifier.Dispose();
 
-             // this is prime time to draw gui stuff 
 
-             context.DrawLine(_pen, _cursorPoint + new Vector(-20, 0), _cursorPoint + new Vector(20, 0));
 
-             context.DrawLine(_pen, _cursorPoint + new Vector(0, -20), _cursorPoint + new Vector(0, 20));
 
-             clip.Dispose();
 
-             // oh and draw again when you can, no rush, right? 
 
-             Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
 
-         }
 
-         private Point UIPointToWorldPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation)
 
-         {
 
-             Point workingPoint = new Point(inPoint.X, -inPoint.Y);
 
-             workingPoint += new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d);
 
-             workingPoint /= scale;
 
-             workingPoint = Matrix.CreateRotation(rotation).Transform(workingPoint);
 
-             workingPoint += new Vector(viewportCenterX, viewportCenterY);
 
-             return workingPoint;
 
-         }
 
-         private Point WorldPointToUIPoint(Point inPoint, double viewportCenterX, double viewportCenterY, double scale, double rotation)
 
-         {
 
-             Point workingPoint = new Point(inPoint.X, inPoint.Y);
 
-             workingPoint -= new Vector(viewportCenterX, viewportCenterY);
 
-             // undo rotation
 
-             workingPoint = Matrix.CreateRotation(-rotation).Transform(workingPoint);
 
-             workingPoint *= scale;
 
-             workingPoint -= new Vector(-this.Bounds.Width / 2.0d, this.Bounds.Height / 2.0d);
 
-             workingPoint = new Point(workingPoint.X, -workingPoint.Y);
 
-             return workingPoint;
 
-         }
 
-     }
 
- }
 
 
  |