예제 #1
0
        private bool lineCross(SKPoint loc, SKPoint vec, SKPoint c)
        {
            if (SKPoint.Distance(loc, c) < radius)
            {
                return(true);
            }
            SKPoint vc = c - loc;
            float   d  = vc.X * vec.X + vc.Y * vec.Y;

            if (d < 0)
            {
                return(false);
            }
            float v = vec.LengthSquared;

            if (d >= v)
            {
                return(false);
            }
            float s = vc.X * vec.Y - vc.Y * vec.X;

            if (s * s < radius * radius * v)
            {
                return(true);
            }
            return(false);
        }
예제 #2
0
        public void SelectNearestPoint(SKPoint tapLocation)
        {
            var point = Points.First(x =>
                                     SKPoint.Distance(x, tapLocation) == Points.Min(y => SKPoint.Distance(y, tapLocation)));

            SelectedPoint = point;
        }
예제 #3
0
        private void eliteSliderTouched(object eventSender, SKTouchEventArgs eventArgs)
        {
            switch (eventArgs.ActionType)
            {
            case SKTouchAction.Pressed:
            {
                float givenDistance = SKPoint.Distance(this.sliderThumbPoint, eventArgs.Location);

                if (givenDistance <= this.sliderThumbSize)
                {
                    this.sliderThumbPointCanMove = true;
                    this.sliderThumbSizeUpdated  = this.sliderThumbSize + 8;
                    this.InvalidateSurface();
                }
            }
            break;

            case SKTouchAction.Released:
            {
                if (this.sliderThumbPointCanMove)
                {
                    this.sliderThumbSizeUpdated = this.sliderThumbSize;
                    this.InvalidateSurface();
                }

                this.sliderThumbPointCanMove = false;
            }
            break;

            case SKTouchAction.Moved:
            {
                if (this.sliderThumbPointCanMove)
                {
                    if (eventArgs.Location.X <= this.sliderThumbSize ||
                        eventArgs.Location.X >= this.canvasWidth - this.sliderThumbSize)
                    {
                        return;
                    }

                    int thumbOffset = (int)(eventArgs.Location.X - this.sliderThumbSize - 10);
                    int barWidth    = this.sliderBarWidth - this.sliderThumbSize - 10;

                    decimal onePixelInPercent = 100m / barWidth;
                    decimal pixelInPercent    = onePixelInPercent * thumbOffset;
                    decimal sliderPercent     = Math.Ceiling(pixelInPercent);

                    this.OnValueChanged((int)sliderPercent);

                    this.sliderThumbPointUpdated    = new SKPoint(eventArgs.Location.X, this.sliderThumbPoint.Y);
                    this.sliderThumbPointHasUpdated = true;
                    this.InvalidateSurface();
                }
            }
            break;
            }

            eventArgs.Handled = true;
        }
예제 #4
0
        private void SKCanvasView_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;
            var height = canvas.DeviceClipBounds.Height;
            var width  = canvas.DeviceClipBounds.Width;

            var boxHeight = PageHeight * .2;
            var boxWidth  = PageWidth * .9;

            var vertices = new SKPoint[]
            {
                new SKPoint((float)width * .33f, 0f),
                new SKPoint((float)width * .66f, (float)height),
                new SKPoint((float)width, 0f),
            };

            var vertices1 = new SKPoint[]
            {
                new SKPoint((float)width * .5f, 0f),
                new SKPoint((float)width * .85f, (float)height + (float)height * .1f),
                new SKPoint((float)width + (float)width * .25f, 0f),
            };

            var offset = SKPoint.Distance(vertices[0], vertices[2]);

            var point1 = new SKPoint((float)width * .66f, (float)height);
            var point2 = new SKPoint((float)width * .85f, (float)height + (float)height * .1f);

            var distance = SKPoint.Distance(point1, point2);

            var midPoint = new SKPoint(point1.X + distance / 2, point1.Y - point1.Y * .20f);

            var vertices2 = new SKPoint[]
            {
                new SKPoint((float)width * .5f, 0f),
                midPoint,
                new SKPoint((float)width, 0f),
            };


            var triangleFill = new SKPaint()
            {
                Style = SKPaintStyle.StrokeAndFill,
                Color = SKColor.Parse("#00BE4F"),
            };

            canvas.Clear();

            canvas.Save();
            canvas.DrawRect(0f, 0f, (float)boxWidth, (float)boxHeight, rect);
            canvas.DrawVertices(SKVertexMode.Triangles, vertices, new SKColor[] { SKColor.Parse("#00BE4F"), SKColor.Parse("#00BE4F"), SKColor.Parse("#00BE4F") }, triangleFill);
            canvas.DrawVertices(SKVertexMode.Triangles, vertices1, new SKColor[] { SKColor.Parse("#00BE4F"), SKColor.Parse("#00BE4F"), SKColor.Parse("#00BE4F") }, triangleFill);
            canvas.DrawVertices(SKVertexMode.Triangles, vertices2, new SKColor[] { SKColor.Parse("#19C75D"), SKColor.Parse("#19C75D"), SKColor.Parse("#19C75D") }, triangleFill);
            canvas.Restore();
        }
        private void DrawGrdientLines(ICollection <SKPaint> paints, SKCanvas canvas, SKRect drawRect, ICollection <SKPoint> points)
        {
            if (paints.Count < 2)
            {
                throw new Exception();
            }

            try
            {
                var start    = points.First();
                var distance = points
                               .Skip(1)
                               .Select(
                    nextPoint =>
                {
                    var distance = SKPoint.Distance(start, nextPoint);
                    start        = nextPoint;
                    return(distance);
                }
                    )
                               .ToArray();

                var fullDistance = distance.Sum();

                var dist = 0f;
                start = points.First();
                points.Skip(1)
                .ForEach(
                    (nextPoint, index) =>
                {
                    using var paint = new SKPaint
                          {
                              Shader = SKShader.CreateLinearGradient(
                                  start,
                                  nextPoint,
                                  new[]
                        {
                            CalculateColor(dist / fullDistance, paints.Select(v => v.Color).ToArray()),
                            CalculateColor((dist + distance[index]) / fullDistance, paints.Select(v => v.Color).ToArray()),
                        },
                                  SKShaderTileMode.Clamp
                                  )
                          };
                    dist += distance[index];
                    canvas.DrawLine(start, nextPoint, paint);
                    start = nextPoint;
                }
                    );
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
예제 #6
0
        public void PointsAndVectors()
        {
            var point1 = new SKPoint(50, 50);
            var point2 = new SKPoint(110, 200);

            var vector   = point2 - point1;
            var distance = SKPoint.Distance(point1, point2);

            Assert.Equal("{X=60, Y=150}", vector.ToString());
            Assert.Equal(161.55495, Math.Round(distance, 5));
        }
            public override ICollection <ISelectable> Intersect(SKPoint point, float radius)
            {
                var intersect = SKPoint.Distance(point, _point) <= radius;

                if (!intersect)
                {
                    return(Array.Empty <ISelectable>());
                }

                return(new ISelectable[] { Value, Value.Course });
            }
예제 #8
0
            public float Scaling()
            {
                if (fingerOne == null || fingerTwo == null)
                {
                    return(1.0f);
                }
                float initDist = Math.Max(1, SKPoint.Distance(fingerOne.initialLocation, fingerTwo.initialLocation));
                float dist     = Math.Max(1, SKPoint.Distance(fingerOne.currentLocation, fingerTwo.currentLocation));
                float scaling  = Math.Max(dist / initDist, 0.1f);

                return(scaling);
            }
예제 #9
0
        public override void MouseDown(NSEvent e)   // handle MouseDown, MouseDrag, MouseUp, MouseClick
        {
            base.MouseDown(e);
            (CGPoint native, SKPoint location) = ConvertToCanvasPoint(e);
            KGui.kControls.CloseOpenMenu();

            bool isDragging = false;
            bool isTracking = true;

            while (isTracking)
            {
                if (e.Type == NSEventType.LeftMouseDown)
                {
                    // mouse down
                    KGui.kControls.CloseOpenMenu();
                    mouseDownPoint = location;
                }
                else if (e.Type == NSEventType.LeftMouseUp)
                {
                    // mouse up
                    isTracking = false;
                    if (isDragging)
                    {
                        // end of dragging
                        touch.onTouchSwipeOrMouseDragEnd?.Invoke(mouseDownPoint, location);
                    }
                    else
                    {
                        // mouse click
                        touch.onTouchDoubletapOrMouseClick?.Invoke(location);
                    }
                }
                else if (e.Type == NSEventType.LeftMouseDragged)     // generated only when the mouse is down and moving
                {
                    if (isDragging)
                    {
                        touch.onTouchSwipeOrMouseDrag?.Invoke(mouseDownPoint, location);
                        // mouse dragging
                    }
                    else if (SKPoint.Distance(location, mouseDownPoint) > 4)
                    {
                        isDragging = true;
                    }
                    showTooltip = false; UpdateTooltip(e);
                }
                if (isTracking)
                {
                    e = Window.NextEventMatchingMask(NSEventMask.LeftMouseDragged | NSEventMask.LeftMouseUp);
                    (native, location) = ConvertToCanvasPoint(e);
                }
            }
        }
예제 #10
0
        public void OnTouchMoved(SkiTouch touch)
        {
            var pointPixels = touch.PointPixels;

            _movementDistanceDp += _convertPixelsToDp.Invoke((float)_lastTouchPixels.Distance(pointPixels));
            _lastTouchPixels     = pointPixels;

            if (_movementDistanceDp > GetTapDistanceDp(touch.DeviceType))
            {
                MovedTooFarToBeATap = true;
                TouchMovedWhileDragging?.Invoke(touch);
            }
        }
        protected void Delta(SKPoint currentPoint)
        {
            var delta      = LastDeltaPoint - currentPoint;
            var destantion = SKPoint.Distance(LastDeltaPoint, currentPoint);

            LastDeltaPoint = currentPoint;

            if (destantion >= MoveToleranceRadius && _canMove)
            {
                _subOperation = _mouseOperationMove;
            }

            //_mapSettingsController.OffsetByControlPoint(delta);
        }
        protected override void OnTouch(SKTouchEventArgs e)
        {
            switch (e.ActionType)
            {
            case SKTouchAction.Entered:
                break;

            case SKTouchAction.Pressed:
                _gestureCompleted      = false;
                _gestureDurationMillis = 0;
                _dragDistance          = 0.0f;

                _previousTouchLocation = e.Location;
                _gestureSW             = Stopwatch.StartNew();
                break;

            case SKTouchAction.Moved:
                _dragDistance         += SKPoint.Distance(e.Location, _previousTouchLocation);
                _previousTouchLocation = e.Location;
                break;

            case SKTouchAction.Released:
                _gestureDurationMillis = _gestureSW.ElapsedMilliseconds;
                _gestureCompleted      = true;
                break;

            case SKTouchAction.Cancelled:
                break;

            case SKTouchAction.Exited:
                break;

            case SKTouchAction.WheelChanged:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (_gestureCompleted && _dragDistance < 50.0f && _gestureDurationMillis <= 120)
            {
                // Tap!
                Console.WriteLine($"Tap: distance={_dragDistance}px duration={_gestureDurationMillis}ms");

                OnTap();
            }

            e.Handled = true;
        }
예제 #13
0
        private float[] GetEuclideanDistance(SKPoint center, SKRect rect)
        {
            var points = _gradient.Size.IsCorner() ?
                         GetCornerPoints(rect) :
                         GetSidePoints(center, rect);

            var distances = new float[points.Length];

            for (var i = 0; i < distances.Length; i++)
            {
                distances[i] = SKPoint.Distance(center, points[i]);
            }

            return(distances);
        }
예제 #14
0
        private void DrawCircle(SKPath path, SKCanvas canvas)
        {
            var     start = path.Points.First();
            SKPoint end   = path.LastPoint;

            var distance = SKPoint.Distance(start, end);

            if (distance == 0)
            {
                return;
            }

            var radius = Math.Abs(distance / 2);

            canvas.DrawCircle(start, radius, _paint);
        }
예제 #15
0
        protected override bool OnChange(object[] args)
        {
            if (!_selectRectangle)
            {
                _selectRectangle = SKPoint.Distance(_startPointControl, _currentPointControl) >= OperationOptions.RectangleToleranceRadius;
                if (_selectRectangle)
                {
                    _managerCursor.SetCursor(CursorType.ArrowSelectMany);
                    _operationLayer.AddDraw(DrawRect);
                }
            }

            if (_selectRectangle)
            {
                _operationLayer.Invalidate();
            }

            return(true);
        }
예제 #16
0
        public float MinimalDistance(SKPoint point)
        {
            var pointOnLine       = PerpendicularPointOnLine(point);
            var destPerpendicular = OnLine(pointOnLine) ? SKPoint.Distance(pointOnLine, point) : default(float?);
            var dest1             = SKPoint.Distance(point, Point1);
            var dest2             = SKPoint.Distance(point, Point2);
            var min = dest1;

            if (dest2 < min)
            {
                min = dest2;
            }

            if (destPerpendicular.HasValue && destPerpendicular.Value < min)
            {
                min = destPerpendicular.Value;
            }

            return(min);
        }
예제 #17
0
        private void FindClosestItem(float x)
        {
            var closest = float.MaxValue;

            if (ChartEntries == null)
            {
                return;
            }

            foreach (var xVal in ChartValueItemsXPoints.Select(x => x.Item2))
            {
                var distance = SKPoint.Distance(new SKPoint(x, 0), new SKPoint(xVal, 0));

                if (distance < closest)
                {
                    closest      = distance;
                    TouchedPoint = new SKPoint(xVal, 0);
                }
            }
        }
            public static PinchValue FromLocations(SKPoint[] locations)
            {
                if (locations == null || locations.Length < 2)
                {
                    throw new ArgumentException();
                }

                var centerX = 0.0;
                var centerY = 0.0;

                foreach (var location in locations)
                {
                    centerX += location.X;
                    centerY += location.Y;
                }
                centerX /= locations.Length;
                centerY /= locations.Length;

                var radius = SKPoint.Distance(new SKPoint((float)centerX, (float)centerY), locations[0]);
                var angle  = Math.Atan2(locations[1].Y - locations[0].Y, locations[1].X - locations[0].X) * 180.0 / Math.PI;

                return(new PinchValue((float)centerX, (float)centerY, radius, (float)angle));
            }
예제 #19
0
        private void SKCanvasView_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;

            if (Selected)
            {
                var height = (float)canvas.DeviceClipBounds.Height;
                var width  = (float)canvas.DeviceClipBounds.Width;

                var start  = new SKPoint(width * .75f, 0);
                var middle = new SKPoint(width, 0);

                var triangleSideLength = SKPoint.Distance(start, middle);
                var end = new SKPoint(width, triangleSideLength);

                var points = new SKPoint[]
                {
                    start,
                    middle,
                    end,
                };

                canvas.Clear();
                canvas.Save();

                canvas.DrawVertices(SKVertexMode.TriangleFan, points, new SKColor[] { SKColor.Parse("#0EBA46"), SKColor.Parse("#0EBA46"), SKColor.Parse("#0EBA46") }, paint);
                canvas.Save();

                canvas.Translate(width * .87f, height * .05f);
                canvas.DrawPath(CheckPath, LinePaint);
            }
            else
            {
                canvas.Clear(SKColor.Parse("#F5F7F9"));
            }
        }
예제 #20
0
 public bool DoubleTapped()
 {
     return(Tapped() && (lastTap != null) && (previousTap != null) &&
            SKPoint.Distance(lastTap.initialLocation, previousTap.initialLocation) < 50 * DeviceDisplay.MainDisplayInfo.Density &&
            TimeLib.Precedes(lastTap.initialTime, previousTap.initialTime.AddSeconds(0.3)));
 }
예제 #21
0
        private void OnTouchEffectAction(TouchActionType type, SKPoint point)
        {
            switch (type)
            {
            case TouchActionType.Pressed:
                if (ticks == 0)
                {
                    ticks = DateTime.Now.Ticks;
                    Device.StartTimer(TimeSpan.FromMilliseconds(20), () =>
                    {
                        canvasView.InvalidateSurface();
                        return(ticks != 0);
                    });
                }

                if (completedPaths != null)
                {
                    Completed last = completedPaths.Last();
                    if (SKPoint.Distance(last.path.LastPoint, point) > radius / 2)
                    {
                        break;
                    }
                }
                inProgressPath = new SKPath();
                inProgressPath.MoveTo(point);
                canvasView.InvalidateSurface();
                break;

            case TouchActionType.Moved:
                if (inProgressPath == null)
                {
                    break;
                }
                inProgressPath.LineTo(point);
                // adding index of circle which was touched/passed
                SKPoint vec   = inProgressPath.LastPoint - point;
                bool    cross = false;

                foreach (Circle c in circleList)
                {
                    if (circleList.IndexOf(c) == numCircles - 1 && c.fill == true)
                    {
                        if (ticks != 0)
                        {
                            double s = 0.01 * Math.Floor(0.00001 * (DateTime.Now.Ticks - ticks));
                            main.addResult(s, numCircles);
                            ticks = 0;
                        }
                        endGameAsync();
                        return;
                    }
                    if (c.fill)
                    {
                        continue;
                    }
                    if (lineCross(point, vec, c.center))
                    {
                        int ind = circleList.IndexOf(c);
                        if (ind == 0 || circleList.ElementAt(ind - 1).fill)
                        {
                            c.fill = true;
                            OnTouchEffectAction(TouchActionType.Released, point);
                            turn = !turn;
                            OnTouchEffectAction(TouchActionType.Pressed, point);
                            cross = true;
                            break;
                        }
                        break;
                    }
                }
                if (!cross)
                {
                    canvasView.InvalidateSurface();
                }

                break;

            case TouchActionType.Released:
                if (inProgressPath == null)
                {
                    break;
                }
                // My Random Color Implementation
                Random rand = new Random();
                Byte[] rgb  = new Byte[3];
                rand.NextBytes(rgb);
                paint.Color = new SKColor(rgb[0], rgb[1], rgb[2]);
                Completed completed = new Completed(inProgressPath, turn ? 0 : 1);
                if (completedPaths == null)
                {
                    completedPaths = new List <Completed>();
                }
                completedPaths.Add(completed);
                inProgressPath = null;
                break;

            case TouchActionType.Cancelled:
                inProgressPath = null;
                canvasView.InvalidateSurface();
                break;
            }
        }
예제 #22
0
 static float GetLineLength(SKPoint start, SKPoint end)
 {
     return(SKPoint.Distance(start, end));
 }
예제 #23
0
        // drawing circles randomly at the start
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            canvas = args.Surface.Canvas;
            canvas.Clear();

            int width  = args.Info.Width;
            int height = args.Info.Height;
            int r      = radius = Math.Min(width, height) / 24;


            if (circleList == null)
            {
                Random rand2 = new Random();
                circleList = new List <Circle>();
                while (circleList.Count() < numCircles)
                {
                    SKPoint p = new SKPoint();
                    p.X = rand2.Next(r, width - r);
                    p.Y = rand2.Next(r, height - r);


                    bool toClose = false;

                    foreach (Circle pi in circleList)
                    {
                        if (SKPoint.Distance(p, pi.center) > 2 * r)
                        {
                            continue;
                        }
                        toClose = true;
                        break;
                    }
                    if (!toClose)
                    {
                        circleList.Add(new Circle(p));
                    }
                }
            }

            // continuously drawing the same circles underneath the lines as a part of the background
            int num = 1;

            foreach (Circle p in circleList)
            {
                canvas.DrawCircle(p.center, r, p.fill ? paintAfter : paint);
                Circle newP = new Circle(p.center, p.fill);
                newP.center.Y += 25;
                canvas.DrawText(circleList.IndexOf(p) + 1 + "", newP.center, newP.fill ? paintNumAfter : paintNumInit);
                num += 1;
            }

            if (completedPaths != null)
            {
                foreach (Completed c in completedPaths)
                {
                    canvas.DrawPath(c.path, c.player == 0 ? paintPlayer1 : paintPlayer2);
                }
            }

            if (inProgressPath != null)
            {
                canvas.DrawPath(inProgressPath, turn ? paintPlayer1 : paintPlayer2);
            }

            foreach (Circle s in circleIntersections)
            {
                canvas.DrawCircle(s.center, r / 12, paintAfter);
            }

            if (ticks != 0)
            {
                double s = 0.01 * Math.Floor(0.00001 * (DateTime.Now.Ticks - ticks));
                double m = Math.Floor(s / 60);
                s -= 60 * m;

                canvas.DrawText(m + ":" + s.ToString("00.00"), 300, 50, paintNumInit);
            }
        }
예제 #24
0
        private bool OnTouchReleased(SKTouchEventArgs e)
        {
            var handled = false;

            var ticks         = DateTime.Now.Ticks;
            var location      = e.Location;
            var releasedTouch = touches[e.Id];

            touches.Remove(e.Id);

            var points = GetInContactTouchPoints();

            // no more fingers on the screen
            if (points.Length == 0)
            {
                // check to see if it was a fling
                var velocity = flingTracker.CalculateVelocity(e.Id, ticks);
                if (Math.Abs(velocity.X * velocity.Y) > (flingVelocityThreshold * flingVelocityThreshold))
                {
                    var args = new SKFlingDetectedEventArgs(velocity.X, velocity.Y);
                    OnFlingDetected(args);
                    handled = args.Handled;
                }

                // when tapping, the finger never goes to exactly the same location
                var isAround = SKPoint.Distance(releasedTouch.Location, initialTouch) < touchSlopPixels;
                if (isAround && (ticks - releasedTouch.Tick) < (e.DeviceType == SKTouchDeviceType.Mouse ? shortClickTicks : longTapTicks))
                {
                    // add a timer to detect the type of tap (single or multi)
                    void TimerHandler(object state)
                    {
                        var l = (SKPoint)state;

                        if (!handled)
                        {
                            if (tapCount > 1)
                            {
                                var args = new SKTapDetectedEventArgs(location, tapCount);
                                OnDoubleTapDetected(args);
                                handled = args.Handled;
                            }
                            else
                            {
                                var args = new SKTapDetectedEventArgs(l);
                                OnSingleTapDetected(args);
                                handled = args.Handled;
                            }
                        }
                        tapCount = 1;
                        multiTapTimer?.Dispose();
                        multiTapTimer = null;
                    };
                    multiTapTimer = new Timer(TimerHandler, location, delayTapMilliseconds, -1);
                }
                else if (isAround && (ticks - releasedTouch.Tick) >= longTapTicks)
                {
                    // if the finger was down for a long time, then it is a long tap
                    if (!handled)
                    {
                        var args = new SKTapDetectedEventArgs(location);
                        OnLongPressDetected(args);
                        handled = args.Handled;
                    }
                }
            }

            // update the fling tracker
            flingTracker.RemoveId(e.Id);

            if (points.Length == 1)
            {
                // if there is still 1 finger on the screen, then try start a new gesture
                var args = new SKGestureEventArgs(points);
                OnGestureStarted(args);
                handled = args.Handled;

                // if no gesture was started, then we will handle it
                if (!handled)
                {
                    touchMode             = TouchMode.Single;
                    previousValues.Center = points[0];
                    handled = true;
                }
            }

            if (!handled)
            {
                // the gesture was not handled, so end it
                var args = new SKGestureEventArgs(points);
                OnGestureEnded(args);
                handled = args.Handled;

                if (points.Length == 0)
                {
                    touchMode = TouchMode.None;
                }
            }

            return(handled);
        }
예제 #25
0
        private async void Chemical_Searched(object sender, EventArgs e)
        {
            try
            {
                if (!await CheckNetworkStatus() || completedPaths.Count == 0)
                {
                    return;
                }

                guidePaths.Clear();

                var      carbon   = eb.CreateElement("C");
                var      atomdict = new Dictionary <SKPoint, AtomNode>();
                Molecule mole     = new Molecule();


                foreach (var x in completedPaths)
                {
                    var line = x.GetLine();

                    var first  = line[0];
                    var second = line[1];


                    if (!atomdict.ContainsKey(first))
                    {
                        var atom = diffElements.ContainsKey(first)
                            ? new AtomNode(diffElements[first])
                            : new AtomNode(carbon);
                        atomdict.Add(first, atom);
                        mole = new Molecule(atom);
                    }

                    if (!atomdict.ContainsKey(second))
                    {
                        var keys  = atomdict.Keys;
                        var point = keys.FirstOrDefault(pt => Math.Abs(SKPoint.Distance(pt, second)) <= 2);
                        if (point != default)
                        {
                            second = point;
                        }
                        else
                        {
                            var atom2 = diffElements.ContainsKey(second)
                                ? new AtomNode(diffElements[second])
                                : new AtomNode(carbon);
                            atomdict.Add(second, atom2);
                        }
                    }

                    mole.AddBond(x.Order, atomdict[first], atomdict[second]);
                }

                var smiles = mole.ToSMILES().Replace("=", "%3D");
                if (smiles.Contains("XXOVERFLOWXX"))
                {
                    throw new StackOverflowException();
                }

                smiles = smiles.Replace("#", "%23");
                var mass    = mole.GetMolecularMass();
                var formula = mole.GetMolecularFormula();
                await Shell.Current.GoToAsync($"resultPage?mass={mass}&search={smiles}&formula={formula}");
            }
            catch (Exception)
            {
                DisplayErrorMessage(sender, e);
            }
        }
예제 #26
0
        /// <summary>
        /// Processes touch input
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void TouchEffect_OnTouchAction(object sender, TouchActionEventArgs args)
        {
            switch (args.Type)
            {
            // An individual press
            // If canvas is blank then it purely suggests the guide paths
            // If the canvas is not blank then the touch only registers if it hits on an existing atom
            case TouchActionType.Pressed:
                if (!inProgressPaths.ContainsKey(args.Id))
                {
                    guidePaths.Clear();
                    BondPath path  = new BondPath();
                    var      pixel = ConvertToPixel(args.Location);

                    if (completedPaths.Count > 0)
                    {
                        foreach (var pth in completedPaths)
                        {
                            if (SKPoint.Distance(pth[0], pixel) < 50)
                            {
                                pixel = pth[0];
                                SuggestGuidePaths(pixel);
                                SuggestAltGuidePaths(pixel);
                                break;
                            }
                            if (SKPoint.Distance(pth.LastPoint, pixel) < 50)
                            {
                                pixel = pth.LastPoint;
                                SuggestGuidePaths(pixel);
                                SuggestAltGuidePaths(pixel);
                                break;
                            }
                        }
                        GuidePathTrim(pixel);
                    }

                    path.MoveTo(pixel);
                    inProgressPaths.Add(args.Id, path);



                    if (completedPaths.Count == 0)
                    {
                        SuggestGuidePaths(pixel);
                        SuggestAltGuidePaths(pixel);
                    }


                    canvasView.InvalidateSurface();
                }
                break;

            // Drag the line to the end of the template line and then it becomes a 'completed line'
            case TouchActionType.Moved:
                if (inProgressPaths.ContainsKey(args.Id))
                {
                    BondPath path       = inProgressPaths[args.Id];
                    var      firstPoint = path[0];
                    path.Rewind();
                    path.MoveTo(firstPoint);
                    path.LineTo(ConvertToPixel(args.Location));

                    if (guidePaths.ContainsKey(firstPoint))
                    {
                        BondPath linqPath = guidePaths[firstPoint]
                                            .FirstOrDefault(pth => SKPoint.Distance(pth.LastPoint, path.LastPoint) < 30);
                        if (linqPath != null)
                        {
                            guidePaths.Remove(linqPath[0]);
                            linqPath.Order = BondOrderFromPicker();
                            completedPaths.Add(linqPath);
                            undoStack.Push("path");
                            MakeNewPathFromPoint(args, linqPath.LastPoint);
                            SuggestGuidePaths(linqPath.LastPoint);
                            SuggestAltGuidePaths(linqPath.LastPoint);
                            GuidePathTrim(linqPath.LastPoint);
                        }
                    }
                    canvasView.InvalidateSurface();
                }

                break;

            case TouchActionType.Released:
                if (inProgressPaths.ContainsKey(args.Id))
                {
                    inProgressPaths.Remove(args.Id);
                    canvasView.InvalidateSurface();
                }

                break;

            case TouchActionType.Cancelled:
                if (inProgressPaths.ContainsKey(args.Id))
                {
                    inProgressPaths.Remove(args.Id);
                    canvasView.InvalidateSurface();
                }

                break;
            }
        }