Exemplo n.º 1
0
        // The base class gathers mouse events and calls AnalyzeGesture()

        protected override bool AddFiltered(Util.WinForms.DragState state_, DragPoint dp)
        {
            DragState state = (DragState)state_;

            if (state.ClickedShape != null && state.ClickedShape.AllowsDrag)
            {
                return(false);                // gesture recognition is off
            }
            return(base.AddFiltered(state, dp));
        }
Exemplo n.º 2
0
        protected override void AnalyzeGesture(Util.WinForms.DragState state_, bool mouseUp)
        {
            // TODO: Analyze on separate thread and maybe even draw on a separate thread.
            //       Otherwise, on slow computers, mouse input may be missed or laggy due to drawing/analysis
            DragState state    = (DragState)state_;
            var       adorners = Control.DragAdornerShapes;

            adorners.Clear();
            Shape newShape = null;
            IEnumerable <Shape> eraseSet = null;

            if (state.IsDrag)
            {
                if (state.ClickedShape != null && state.ClickedShape.AllowsDrag)
                {
                    HandleShapeDrag(state);
                }
                else
                {
                    List <PointT> simplified;
                    bool          cancel;
                    eraseSet = RecognizeScribbleForEraseOrCancel(state, out cancel, out simplified);
                    if (eraseSet != null)
                    {
                        ShowEraseDuringDrag(state, adorners, eraseSet, simplified, cancel);
                    }
                    else
                    {
                        bool potentialSelection = false;
                        newShape = DetectNewShapeDuringDrag(state, adorners, out potentialSelection);
                        if (potentialSelection)
                        {
                            var selecting = ShapesInside(newShape.BBox).ToList();
                            if (selecting.Count != 0)
                            {
                                newShape.Style = SelectorBoxStyle;
                            }
                        }
                    }
                }
            }

            if (mouseUp)
            {
                adorners.Clear();
                HandleMouseUp(state, newShape, eraseSet);
            }
            else if (newShape != null)
            {
                newShape.AddLLShapesTo(adorners);
                newShape.Dispose();
            }

            Control.DragAdornersChanged();
        }
Exemplo n.º 3
0
        /// <summary>Adds a point to DragState with a filtering algorithm. The
        /// default filtering algorithm supports "backing up the mouse" for erasure.</summary>
        /// <returns>true if a point was added, false if not.</returns>
        protected virtual bool AddFiltered(DragState state, DragPoint dp)
        {
            var points = state.MousePoints;

            if (points.Count < 2)
            {
                return(AddIfFarEnough(points, dp));
            }

            var newSeg = (LineSegment <float>)points.Last.Point.To(dp.Point);
            // Strategy:
            // 1. Stroke the new segment with a simple rectangle with no endcap.
            //    The rectangle will be a thin box around the point (halfwidth
            //    is 1..2)
            var newRect   = SimpleStroke(newSeg, EraseThreshold1);
            var newRectBB = newRect.ToBoundingBox();

            // 2. Identify the most recent intersection point between this rectangle
            //    (newRect) and the line being drawn. (if there is no such point,
            //    there is no erasure. Done.)
            // 2b. That intersection point is the one _entering_ the rectangle. Find
            //    the previous intersection point, the one that exits the rectangle.
            //    this is the beginning of the region to potentially erase.
            var           older       = points.Reverse().AdjacentPairs().Select(pair => pair.B.Point.To(pair.A.Point));
            Point <float> beginning   = default(Point <float>);
            bool          keepLooking = false;
            int           offs        = 0;
            var           e           = older.GetEnumerator();

            for (; e.MoveNext(); offs++)
            {
                var seg  = e.Current;
                var list = FindIntersectionsWith(seg, newRect, true).ToList();
                if (list.Count != 0)
                {
                    var min = list.MinOrDefault(p => p.A);
                    beginning = min.B;
                    if (!(offs == 0 && min.A == 1))
                    {
                        if (keepLooking || !PolygonMath.IsPointInPolygon(newRect, seg.A))
                        {
                            break;
                        }
                        keepLooking = true;
                    }
                }
                else if (offs == 0)
                {
                }                                       // todo: use IsPointInPolygon if itscs unstable
            }

            int iFirst = points.Count - 1 - offs;             // index of the first point inside the region (iFirst-1 is outside)

            if (iFirst > 0)
            {
                // 3. Between here and there, identify the farthest point away from the
                //    new point (dp.Point).
                var region       = ((IList <DragPoint>)points).Slice(iFirst);
                int offsFarthest = region.IndexOfMax(p => (p.Point.Sub(dp.Point)).Quadrance());
                int iFarthest    = iFirst + offsFarthest;
                // 4. Make sure that all the points between here and there are close to
                //    this line (within, say... 8 pixels). If so, we have erasure.
                var seg = dp.Point.To(points[iFarthest].Point);
                if (region.All(p => p.Point.DistanceTo(seg) < EraseThreshold2))
                {
                    // 5. Respond to erasure by deleting all the points between there
                    //    and here, not including the first or last point.
                    // 5b. Consider adding the intersection point found in step 2b to
                    //    the point list, before adding the new point.
                    points.Resize(iFirst);
                    if (points.Count == 0 || (points.Last.Point.Sub(beginning)).Length() >= MinDistBetweenDragPoints)
                    {
                        points.Add(new DragPoint(beginning, 10, points));
                    }
                }
            }

            return(AddIfFarEnough(points, dp));
        }
Exemplo n.º 4
0
 /// <summary>This method is called when the mouse is clicked, for every
 /// mouse move event while the mouse is down, and one last time on mouse up.</summary>
 /// <param name="state">Contains the history of mouse moves since mouse down.</param>
 /// <param name="mouseUp">If true, the gesture is ending because the mouse
 /// button was just released.</param>
 protected abstract void AnalyzeGesture(DragState state, bool mouseUp);