Ejemplo n.º 1
0
 /// <summary>
 /// Refreshes the underlying data structures corresponding to the inkStroke.
 /// </summary>
 public void UpdateInkStrokes(System.Windows.Ink.StrokeCollection inkStrokes)
 {
     foreach (System.Windows.Ink.Stroke inkStroke in inkStrokes)
     {
         UpdateInkStroke(inkStroke);
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculates the position of an error label based upon the bounding box of the elements
        /// causing the error.
        ///
        /// Helper Function
        /// </summary>
        private System.Drawing.Point getLabelPosition(ParseError e, List <System.Windows.Ink.Stroke> iStrokes)
        {
            if (e.errors.Count == 0)
            {
                // TEMP HACK return the origin (or near it) when there are no associated elements
                return(new System.Drawing.Point(10, 10));
            }

            // Get bounding box of strokes in screen space
            System.Drawing.Point bbUpperLeft;
            System.Drawing.Point bbLowerRight;
            System.Windows.Ink.StrokeCollection strokes = new System.Windows.Ink.StrokeCollection();

            foreach (System.Windows.Ink.Stroke s in iStrokes)
            {
                strokes.Add(s);
            }

            System.Windows.Rect strokesBB = strokes.GetBounds();
            bbUpperLeft  = new System.Drawing.Point((int)strokesBB.X, (int)strokesBB.Y);
            bbLowerRight = new System.Drawing.Point((int)strokesBB.Right, (int)strokesBB.Bottom);

            // return position just to the right of the bounding box
            System.Drawing.Point returnPoint =
                new System.Drawing.Point(bbLowerRight.X + 10, bbUpperLeft.Y + 10);

            return(returnPoint);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Deletes a collection of Strokes and updates the Sketch.
 /// </summary>
 /// <param name="iStroke">The Stroke to delete</param>
 public void DeleteStrokes(System.Windows.Ink.StrokeCollection inkStrokes)
 {
     foreach (System.Windows.Ink.Stroke iStroke in inkStrokes)
     {
         DeleteStroke(iStroke);
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Reinitializes error labels when the sketch is zoomed or strokes are moved.
 /// </summary>
 private void sketchPanel_InkTransformed(System.Windows.Rect originalBoundingBox,
                                         System.Windows.Rect newBoundingBox, System.Windows.Ink.StrokeCollection iStrokes, InkTransformEventType eventType)
 {
     // Not currently using error list.
     //if (this.errorList != null)
     //    initErrors();
 }
Ejemplo n.º 5
0
        public static WindowsInk.StrokeCollection ToWindowsStrokes(Collection<NineInk.Stroke> nineStrokes)
        {
            var windowsStrokes = new WindowsInk.StrokeCollection();

            foreach (var stroke in nineStrokes)
                windowsStrokes.Add(ToWindowsStroke(stroke));

            return windowsStrokes;
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Notifies the client that strokes were received from the signalr client.
 /// </summary>
 /// <param name="strokes">The strokes.</param>
 private void StrokesReceivedEvent(System.Windows.Ink.StrokeCollection strokes)
 {
     if (strokes.Any())
     {
         Dispatcher.Invoke(() =>
         {
             mainInkCanvas.Strokes.Add(strokes);
         });
     }
 }
Ejemplo n.º 7
0
        private void Strokes_StrokesChanged(object sender, System.Windows.Ink.StrokeCollectionChangedEventArgs e)
        {
            if (handle)
            {
                _added   = e.Added;
                _removed = e.Removed;

                testiadded.Add(_added);
            }
        }
Ejemplo n.º 8
0
        public static WindowsInk.StrokeCollection ToWindowsStrokes(Collection <NineInk.Stroke> nineStrokes)
        {
            var windowsStrokes = new WindowsInk.StrokeCollection();

            foreach (var stroke in nineStrokes)
            {
                windowsStrokes.Add(ToWindowsStroke(stroke));
            }

            return(windowsStrokes);
        }
Ejemplo n.º 9
0
        public static Collection <NineInk.Stroke> ToNineStrokes(WindowsInk.StrokeCollection windowsStrokes)
        {
            var nineStrokes = new Collection <NineInk.Stroke>();

            foreach (var stroke in windowsStrokes)
            {
                nineStrokes.Add(ToNineStroke(stroke));
            }

            return(nineStrokes);
        }
Ejemplo n.º 10
0
 /// <summary>
 /// InkCanvasStrokesReplacedEventArgs
 /// </summary>
 internal InkCanvasStrokesReplacedEventArgs(Swi.StrokeCollection newStrokes, Swi.StrokeCollection previousStrokes)
 {
     if (newStrokes == null)
     {
         throw new ArgumentNullException("newStrokes");
     }
     if (previousStrokes == null)
     {
         throw new ArgumentNullException("previousStrokes");
     }
     _newStrokes      = newStrokes;
     _previousStrokes = previousStrokes;
 }
Ejemplo n.º 11
0
        //coleccion de cambios del stroke usado para deshacer y rehacer

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Evento que se lanza cuando cambia un objeto Stroke en la colección.Se usa para el manejo de
        ///             de Deshacer y Rehacer </summary>
        ///
        /// <remarks>   Fidi, 11/16/2019. </remarks>
        ///
        /// <param name="sender">   Strokes. </param>
        /// <param name="e">        Evento <b>StrokesChanged</b> </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        private void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
        {
            if (handle)
            {
                _added          = e.Added;
                _removed        = e.Removed;
                undoDone        = false;
                Undo.IsEnabled  = true;
                Undo.Background = Brushes.LightGray;
                redoDone        = true;
                Redo.IsEnabled  = false;
                Redo.Background = Brushes.Transparent;
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// called by base class Insert, Add methods
        /// </summary>
        protected override sealed void InsertItem(int index, Stroke stroke)
        {
            if (stroke == null)
            {
                throw new ArgumentNullException("stroke");
            }
            if (this.IndexOf(stroke) != -1)
            {
                throw new ArgumentException(SR.Get(SRID.StrokeIsDuplicated), "stroke");
            }

            base.InsertItem(index, stroke);

            StrokeCollection addedStrokes = new StrokeCollection();

            ((List <Stroke>)addedStrokes.Items).Add(stroke);
            RaiseStrokesChanged(addedStrokes, null /*removed*/, index);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Calculate the after-erasing Strokes. Only the "out-segments" are left after this operation.
        /// </summary>
        /// <param name="cutAt">Array of intersections indicating the erasing locations</param>
        /// <returns></returns>
        internal StrokeCollection Erase(StrokeIntersection[] cutAt)
        {
            System.Diagnostics.Debug.Assert(cutAt != null);

            // Nothing needs to be erased
            if (cutAt.Length == 0)
            {
                StrokeCollection strokes = new StrokeCollection();
                strokes.Add(this.Clone()); //clip and erase always return clones for this condition
                return(strokes);
            }

            // Two assertions are deferred to the private erase function to avoid duplicate code.
            // 1. AssertSortedNoOverlap
            // 2. Check whether the insegments are out of range with the packets
            StrokeFIndices[] hitSegments = StrokeIntersection.GetHitSegments(cutAt);
            return(this.Erase(hitSegments));
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Issue: what's the return value
        /// </summary>
        /// <param name="path"></param>
        /// <param name="stylusShape"></param>
        /// <returns></returns>
        public StrokeCollection HitTest(IEnumerable <Point> path, StylusShape stylusShape)
        {
            // Check the input parameters
            if (stylusShape == null)
            {
                throw new System.ArgumentNullException("stylusShape");
            }
            if (path == null)
            {
                throw new System.ArgumentNullException("path");
            }
            if (IEnumerablePointHelper.GetCount(path) == 0)
            {
                return(new StrokeCollection());
            }

            // validate input
            ErasingStroke erasingStroke = new ErasingStroke(stylusShape, path);
            Rect          erasingBounds = erasingStroke.Bounds;

            if (erasingBounds.IsEmpty)
            {
                return(new StrokeCollection());
            }
            StrokeCollection hits = new StrokeCollection();

            foreach (Stroke stroke in this)
            {
                // samgeo - Presharp issue
                // Presharp gives a warning when get methods might deref a null.  It's complaining
                // here that 'stroke'' could be null, but StrokeCollection never allows nulls to be added
                // so this is not possible
#pragma warning disable 1634, 1691
#pragma warning suppress 6506
                if (erasingBounds.IntersectsWith(stroke.GetBounds()) &&
                    erasingStroke.HitTest(StrokeNodeIterator.GetIterator(stroke, stroke.DrawingAttributes)))
                {
                    hits.Add(stroke);
                }
#pragma warning restore 1634, 1691
            }

            return(hits);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Clips out all ink outside a given lasso
        /// </summary>
        /// <param name="lassoPoints">lasso</param>
        public void Clip(IEnumerable <Point> lassoPoints)
        {
            // Check the input parameters
            if (lassoPoints == null)
            {
                throw new System.ArgumentNullException("lassoPoints");
            }

            int length = IEnumerablePointHelper.GetCount(lassoPoints);

            if (length == 0)
            {
                throw new ArgumentException(SR.Get(SRID.EmptyArray));
            }

            if (length < 3)
            {
                //
                // if you're clipping with a point or a line with
                // two points, it doesn't matter where the line is or if it
                // intersects any of the strokes, the point or line has no region
                // so technically everything in the strokecollection
                // should be removed
                //
                this.Clear(); //raises the appropriate events
                return;
            }

            Lasso lasso = new SingleLoopLasso();

            lasso.AddPoints(lassoPoints);

            for (int i = 0; i < this.Count; i++)
            {
                Stroke           stroke     = this[i];
                StrokeCollection clipResult = stroke.Clip(stroke.HitTest(lasso));
                UpdateStrokeCollection(stroke, clipResult, ref i);
            }
        }
        /// <summary>
        /// Remove a set of Stroke objects to the collection
        /// </summary>
        /// <param name="strokes">The strokes to remove from the collection</param>
        /// <remarks>Changes to the collection trigger a StrokesChanged event.</remarks>
        public void Remove(StrokeCollection strokes)
        {
            if (strokes == null)
            {
                throw new ArgumentNullException("strokes");
            }
            if (strokes.Count == 0)
            {
                // NOTICE-2004/06/08-WAYNEZEN:
                // We don't throw if an empty collection is going to be removed. And there is no event either.
                // This rule is also applied to invoking Clear() with an empty StrokeCollection.
                return;
            }

            int[] indexes = this.GetStrokeIndexes(strokes);
            if (indexes == null)
            {
                // At least one stroke doesn't exist in our collection. We throw.
                ArgumentException ae = new ArgumentException(SR.Get(SRID.InvalidRemovedStroke), "strokes");
                //
                // we add a tag here so we can check for this in EraserBehavior.OnPointEraseResultChanged
                // to determine if this method is the origin of an ArgumentException we harden against
                //
                ae.Data.Add("System.Windows.Ink.StrokeCollection", "");
                throw ae;
            }

            for (int x = indexes.Length - 1; x >= 0; x--)
            {
                //bypass this.RemoveAt, which calls changed events
                //and call our protected List<Stroke> directly
                //remove from the back so the indexes are correct
                ((List <Stroke>) this.Items).RemoveAt(indexes[x]);
            }

            RaiseStrokesChanged(null /*added*/, strokes, indexes[0]);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Gets label data for a given group of strokes
        /// Precondition: Some strokes are selected (not necessarily for one Shape)
        /// </summary>
        public void UpdateLabelMenu(System.Windows.Ink.StrokeCollection selection)
        {
            // Clear the old selection
            foreach (Button button in this.labelList.Items)
            {
                button.Background = new SolidColorBrush(Colors.White);
            }

            // Record the shape type for each stroke
            List <Domain.ShapeType> possibleShapes = new List <Domain.ShapeType>();

            foreach (Stroke stroke in selection)
            {
                Sketch.Substroke currSubstroke = sketchPanel.InkSketch.GetSketchSubstrokeByInk(stroke);

                Sketch.Shape parentShape = currSubstroke.ParentShape;
                if (parentShape != null)
                {
                    if (!possibleShapes.Contains(parentShape.Type))
                    {
                        possibleShapes.Add(parentShape.Type);
                    }
                }
            }
            // If all of the strokes have the same label and that label is valid, indicate that label by shading it gray
            if (possibleShapes.Count == 1 && !(possibleShapes[0] == null || possibleShapes[0] == new Domain.ShapeType()))
            {
                foreach (Button button in this.labelList.Items)
                {
                    if ((string)button.Content == possibleShapes[0].Name)
                    {
                        button.Background = new SolidColorBrush(Colors.LightGray);
                    }
                }
            }
            return;
        }
        /// <summary>
        /// called by base class set_Item method
        /// </summary>
        protected override sealed void SetItem(int index, Stroke stroke)
        {
            if (stroke == null)
            {
                throw new ArgumentNullException("stroke");
            }
            if (IndexOf(stroke) != -1)
            {
                throw new ArgumentException(SR.Get(SRID.StrokeIsDuplicated), "stroke");
            }

            Stroke removedStroke = this[index];

            base.SetItem(index, stroke);

            StrokeCollection removed = new StrokeCollection();

            ((List <Stroke>)removed.Items).Add(removedStroke);

            StrokeCollection added = new StrokeCollection();

            ((List <Stroke>)added.Items).Add(stroke);
            RaiseStrokesChanged(added, removed, index);
        }
        /// <summary>
        /// Replace
        /// </summary>
        /// <param name="strokesToReplace"></param>
        /// <param name="strokesToReplaceWith"></param>
        public void Replace(StrokeCollection strokesToReplace, StrokeCollection strokesToReplaceWith)
        {
            if (strokesToReplace == null)
            {
                throw new ArgumentNullException(SR.Get(SRID.EmptyScToReplace));
            }
            if (strokesToReplaceWith == null)
            {
                throw new ArgumentNullException(SR.Get(SRID.EmptyScToReplaceWith));
            }

            int replaceCount = strokesToReplace.Count;

            if (replaceCount == 0)
            {
                ArgumentException ae = new ArgumentException(SR.Get(SRID.EmptyScToReplace), "strokesToReplace");
                //
                // we add a tag here so we can check for this in EraserBehavior.OnPointEraseResultChanged
                // to determine if this method is the origin of an ArgumentException we harden against
                //
                ae.Data.Add("System.Windows.Ink.StrokeCollection", "");
                throw ae;
            }

            int[] indexes = this.GetStrokeIndexes(strokesToReplace);
            if (indexes == null)
            {
                // At least one stroke doesn't exist in our collection. We throw.
                ArgumentException ae = new ArgumentException(SR.Get(SRID.InvalidRemovedStroke), "strokesToReplace");
                //
                // we add a tag here so we can check for this in EraserBehavior.OnPointEraseResultChanged
                // to determine if this method is the origin of an ArgumentException we harden against
                //
                ae.Data.Add("System.Windows.Ink.StrokeCollection", "");
                throw ae;
            }


            //validate that none of the relplaceWith strokes exist in the collection
            for (int x = 0; x < strokesToReplaceWith.Count; x++)
            {
                Stroke stroke = strokesToReplaceWith[x];
                if (this.IndexOf(stroke) != -1)
                {
                    throw new ArgumentException(SR.Get(SRID.StrokeIsDuplicated), "strokesToReplaceWith");
                }
            }

            //bypass this.RemoveAt / InsertRange, which calls changed events
            //and call our protected List<Stroke> directly
            for (int x = indexes.Length - 1; x >= 0; x--)
            {
                //bypass this.RemoveAt, which calls changed events
                //and call our protected List<Stroke> directly
                //remove from the back so the indexes are correct
                ((List <Stroke>) this.Items).RemoveAt(indexes[x]);
            }

            if (strokesToReplaceWith.Count > 0)
            {
                //insert at the
                ((List <Stroke>) this.Items).InsertRange(indexes[0], strokesToReplaceWith);
            }


            RaiseStrokesChanged(strokesToReplaceWith, strokesToReplace, indexes[0]);
        }
Ejemplo n.º 20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cutAt">Fragment markers for clipping</param>
        /// <returns>Survived fragments of current Stroke as a StrokeCollection</returns>
        private StrokeCollection Erase(StrokeFIndices[] cutAt)
        {
            System.Diagnostics.Debug.Assert(cutAt != null);
            System.Diagnostics.Debug.Assert(cutAt.Length != 0);

#if DEBUG
            //
            // Assert there are  no overlaps between multiple StrokeFIndices
            //
            AssertSortedNoOverlap(cutAt);
#endif

            StrokeCollection leftovers = new StrokeCollection();
            // Return an empty collection if the entire stroke it to erase
            if ((cutAt.Length == 0) || ((cutAt.Length == 1) && cutAt[0].IsFull))
            {
                return(leftovers);
            }

            StylusPointCollection sourceStylusPoints = this.StylusPoints;
            if (this.DrawingAttributes.FitToCurve)
            {
                sourceStylusPoints = this.GetBezierStylusPoints();
            }

            //
            // Assert the findices are NOT out of range with the packets
            //
            System.Diagnostics.Debug.Assert(false == ((!DoubleUtil.AreClose(cutAt[cutAt.Length - 1].EndFIndex, StrokeFIndices.AfterLast)) &&
                                                      Math.Ceiling(cutAt[cutAt.Length - 1].EndFIndex) > sourceStylusPoints.Count - 1));


            int    i           = 0;
            double beginFIndex = StrokeFIndices.BeforeFirst;
            if (cutAt[0].BeginFIndex == StrokeFIndices.BeforeFirst)
            {
                beginFIndex = cutAt[0].EndFIndex;
                i++;
            }
            for (; i < cutAt.Length; i++)
            {
                StrokeFIndices fragment = cutAt[i];
                if (DoubleUtil.GreaterThanOrClose(beginFIndex, fragment.BeginFIndex))
                {
                    // ISSUE-2004/06/26-vsmirnov - temporary workaround for bugs
                    // in point erasing: drop invalid fragments
                    System.Diagnostics.Debug.Assert(DoubleUtil.LessThan(beginFIndex, fragment.BeginFIndex));
                    continue;
                }


                Stroke stroke = Copy(sourceStylusPoints, beginFIndex, fragment.BeginFIndex);
                // Add the stroke to the output collection
                leftovers.Add(stroke);

                beginFIndex = fragment.EndFIndex;
            }

            if (beginFIndex != StrokeFIndices.AfterLast)
            {
                Stroke stroke = Copy(sourceStylusPoints, beginFIndex, StrokeFIndices.AfterLast);

                // Add the stroke to the output collection
                leftovers.Add(stroke);
            }

            return(leftovers);
        }
Ejemplo n.º 21
0
 internal LassoSelectionChangedEventArgs(StrokeCollection selectedStrokes, StrokeCollection deselectedStrokes)
 {
     _selectedStrokes   = selectedStrokes;
     _deselectedStrokes = deselectedStrokes;
 }
 internal ReadOnlyCollection <GestureRecognitionResult> CriticalRecognize(StrokeCollection strokes)
 {
     return(RecognizeImpl(strokes));
 }
Ejemplo n.º 23
0
        private void Salva(object sender, RoutedEventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter = "InkPaint file (*.fink)|*.fink";

            if (saveFileDialog1.ShowDialog() == true)
            {
                FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create);
                System.Windows.Ink.StrokeCollection strokes = InkPanel.Strokes;
                strokes.Save(fs);
                fs.Close();
            }
            String timeStamp = GetTimestamp(DateTime.Now);

            LatestEvent.Text     = "Saved the canvas";
            LatestEventTime.Text = "1 second ago";
            var timer4 = new DispatcherTimer {
                Interval = TimeSpan.FromSeconds(1)
            };
            var timer3 = new DispatcherTimer {
                Interval = TimeSpan.FromSeconds(2)
            };
            var timer2 = new DispatcherTimer {
                Interval = TimeSpan.FromSeconds(3)
            };
            var timer1 = new DispatcherTimer {
                Interval = TimeSpan.FromSeconds(4)
            };
            var timerend = new DispatcherTimer {
                Interval = TimeSpan.FromSeconds(5)
            };

            timer4.Start();
            timer4.Tick += (sender, args) =>
            {
                timer4.Stop();
                LatestEventTime.Text = "2 seconds ago";
            };
            timer3.Start();
            timer3.Tick += (sender, args) =>
            {
                timer3.Stop();
                LatestEventTime.Text = "3 seconds ago";
            };
            timer2.Start();
            timer2.Tick += (sender, args) =>
            {
                timer2.Stop();
                LatestEventTime.Text = "4 seconds ago";
            };
            timer1.Start();
            timer1.Tick += (sender, args) =>
            {
                timer1.Stop();
                LatestEventTime.Text = "5 seconds ago";
            };
            timerend.Start();
            timerend.Tick += (sender, args) =>
            {
                timerend.Stop();
                LatestEventTime.Text = timeStamp;
            };
        }
 public System.Collections.ObjectModel.ReadOnlyCollection <GestureRecognitionResult> Recognize(StrokeCollection strokes)
 {
     return(default(System.Collections.ObjectModel.ReadOnlyCollection <GestureRecognitionResult>));
 }
Ejemplo n.º 25
0
 /// <summary>
 /// Performs gesture recognition on the StrokeCollection if a gesture recognizer
 /// is present and installed on the system.  If not, this method throws an InvalidOperationException.
 /// To determine if this method will throw an exception, only call this method if
 /// the RecognizerAvailable property returns true.
 ///
 /// </summary>
 /// <param name="strokes">The StrokeCollection to perform gesture recognition on</param>
 /// <returns></returns>
 /// <remarks>Callers must have UnmanagedCode permission to call this API.</remarks>
 public ReadOnlyCollection <GestureRecognitionResult> Recognize(StrokeCollection strokes)
 {
     return(RecognizeImpl(strokes));
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Hit-testing with lasso
        /// </summary>
        /// <param name="lassoPoints">points making the lasso</param>
        /// <param name="percentageWithinLasso">the margin value to tell whether a stroke
        /// is in or outside of the rect</param>
        /// <returns>collection of strokes found inside the rectangle</returns>
        public StrokeCollection HitTest(IEnumerable <Point> lassoPoints, int percentageWithinLasso)
        {
            // Check the input parameters
            if (lassoPoints == null)
            {
                throw new System.ArgumentNullException("lassoPoints");
            }
            if ((percentageWithinLasso < 0) || (percentageWithinLasso > 100))
            {
                throw new System.ArgumentOutOfRangeException("percentageWithinLasso");
            }

            if (IEnumerablePointHelper.GetCount(lassoPoints) < 3)
            {
                return(new StrokeCollection());
            }

            Lasso lasso = new SingleLoopLasso();

            lasso.AddPoints(lassoPoints);

            // Enumerate through the strokes and collect those captured by the lasso.
            StrokeCollection lassoedStrokes = new StrokeCollection();

            foreach (Stroke stroke in this)
            {
                if (percentageWithinLasso == 0)
                {
                    lassoedStrokes.Add(stroke);
                }
                else
                {
                    StrokeInfo strokeInfo = null;
                    try
                    {
                        strokeInfo = new StrokeInfo(stroke);

                        StylusPointCollection stylusPoints = strokeInfo.StylusPoints;
                        double target = strokeInfo.TotalWeight * percentageWithinLasso / 100.0f - Stroke.PercentageTolerance;

                        for (int i = 0; i < stylusPoints.Count; i++)
                        {
                            if (true == lasso.Contains((Point)stylusPoints[i]))
                            {
                                target -= strokeInfo.GetPointWeight(i);
                                if (DoubleUtil.LessThanOrClose(target, 0f))
                                {
                                    lassoedStrokes.Add(stroke);
                                    break;
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (strokeInfo != null)
                        {
                            //detach from event handlers, or else we leak.
                            strokeInfo.Detach();
                        }
                    }
                }
            }

            // Return the resulting collection
            return(lassoedStrokes);
        }
        /// <summary>
        /// Private helper that returns an array of indexes where the specified
        /// strokes exist in this stroke collection.  Returns null if at least one is not found.
        ///
        /// The indexes are sorted from smallest to largest
        /// </summary>
        /// <returns></returns>
        private int[] GetStrokeIndexes(StrokeCollection strokes)
        {
            //to keep from walking the StrokeCollection twice for each stroke, we will maintain an index of
            //strokes to remove as we go
            int[] indexes = new int[strokes.Count];
            for (int x = 0; x < indexes.Length; x++)
            {
                indexes[x] = Int32.MaxValue;
            }

            int currentIndex   = 0;
            int highestIndex   = -1;
            int usedIndexCount = 0;

            for (int x = 0; x < strokes.Count; x++)
            {
                currentIndex = this.OptimisticIndexOf(currentIndex, strokes[x]);
                if (currentIndex == -1)
                {
                    //stroke doe3sn't exist, bail out.
                    return(null);
                }

                //
                // optimize for the most common case... replace is passes strokes
                // in contiguous order.  Only do the sort if we need to
                //
                if (currentIndex > highestIndex)
                {
                    //write current to the next available slot
                    indexes[usedIndexCount++] = currentIndex;
                    highestIndex = currentIndex;
                    continue;
                }

                //keep in sorted order (smallest to largest) with a simple insertion sort
                for (int y = 0; y < indexes.Length; y++)
                {
                    if (currentIndex < indexes[y])
                    {
                        if (indexes[y] != Int32.MaxValue)
                        {
                            //shift from the end
                            for (int i = indexes.Length - 1; i > y; i--)
                            {
                                indexes[i] = indexes[i - 1];
                            }
                        }
                        indexes[y] = currentIndex;
                        usedIndexCount++;

                        if (currentIndex > highestIndex)
                        {
                            highestIndex = currentIndex;
                        }
                        break;
                    }
                }
            }

            return(indexes);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// The implementation behind the public methods AddPoint/AddPoints
        /// </summary>
        /// <param name="points">new points to add to the lasso</param>
        protected override void AddPointsCore(IEnumerable <Point> points)
        {
            System.Diagnostics.Debug.Assert((points != null) && (IEnumerablePointHelper.GetCount(points) != 0));

            // Add the new points to the lasso
            int lastPointIndex = (0 != _lasso.PointCount) ? (_lasso.PointCount - 1) : 0;

            _lasso.AddPoints(points);

            // Do nothing if there's not enough points, or there's nobody listening
            // The points may be filtered out, so if all the points are filtered out, (lastPointIndex == (_lasso.PointCount - 1).
            // For this case, check if the incremental lasso is disabled (i.e., points modified).
            if ((_lasso.IsEmpty) || (lastPointIndex == (_lasso.PointCount - 1) && false == _lasso.IsIncrementalLassoDirty) ||
                (SelectionChanged == null))
            {
                return;
            }

            // Variables for possible HitChanged events to fire
            StrokeCollection strokesHit   = null;
            StrokeCollection strokesUnhit = null;

            // Create a lasso that represents the current increment
            Lasso lassoUpdate = new Lasso();

            if (false == _lasso.IsIncrementalLassoDirty)
            {
                if (0 < lastPointIndex)
                {
                    lassoUpdate.AddPoint(_lasso[0]);
                }

                // Only the points the have been successfully added to _lasso will be added to
                // lassoUpdate.
                for (; lastPointIndex < _lasso.PointCount; lastPointIndex++)
                {
                    lassoUpdate.AddPoint(_lasso[lastPointIndex]);
                }
            }

            // Enumerate through the strokes and update their hit-test results
            foreach (StrokeInfo strokeInfo in this.StrokeInfos)
            {
                Lasso lasso;
                if (true == strokeInfo.IsDirty || true == _lasso.IsIncrementalLassoDirty)
                {
                    // If this is the first time this stroke gets hit-tested with this lasso,
                    // or if the stroke (or its DAs) has changed since the last hit-testing,
                    // or if the lasso points have been modified,
                    // then (re)hit-test this stroke against the entire lasso.
                    lasso = _lasso;
                    strokeInfo.IsDirty = false;
                }
                else
                {
                    // Otherwise, hit-test it against the lasso increment first and then only
                    // those ink points that are in that small lasso need to be hit-tested
                    // against the big (entire) lasso.
                    // This is supposed to be a significant piece of optimization, since
                    // lasso increments are usually very small, they are defined by just
                    // a few points and they don't capture and/or release too many ink nodes.
                    lasso = lassoUpdate;
                }

                // Skip those stroke which bounding box doesn't even intersects with the lasso bounds
                double hitWeightChange = 0f;
                if (lasso.Bounds.IntersectsWith(strokeInfo.StrokeBounds))
                {
                    // Get the stroke node points for the hit-testing.
                    StylusPointCollection stylusPoints = strokeInfo.StylusPoints;

                    // Find out if the lasso update has changed the hit count of the stroke.
                    for (int i = 0; i < stylusPoints.Count; i++)
                    {
                        // Consider only the points that become captured/released with this particular update
                        if (true == lasso.Contains((Point)stylusPoints[i]))
                        {
                            double weight = strokeInfo.GetPointWeight(i);

                            if (lasso == _lasso || _lasso.Contains((Point)stylusPoints[i]))
                            {
                                hitWeightChange += weight;
                            }
                            else
                            {
                                hitWeightChange -= weight;
                            }
                        }
                    }
                }

                // Update the stroke hit weight and check whether it has crossed the margin
                // in either direction since the last update.
                if ((hitWeightChange != 0) || (lasso == _lasso))
                {
                    strokeInfo.HitWeight = (lasso == _lasso) ? hitWeightChange : (strokeInfo.HitWeight + hitWeightChange);
                    bool isHit = DoubleUtil.GreaterThanOrClose(strokeInfo.HitWeight, strokeInfo.TotalWeight * _percentIntersect / 100f - Stroke.PercentageTolerance);

                    if (strokeInfo.IsHit != isHit)
                    {
                        strokeInfo.IsHit = isHit;
                        if (isHit)
                        {
                            // The hit count became greater than the margin percentage, the stroke
                            // needs to be reported for selection
                            if (null == strokesHit)
                            {
                                strokesHit = new StrokeCollection();
                            }
                            strokesHit.Add(strokeInfo.Stroke);
                        }
                        else
                        {
                            // The hit count just became less than the margin percentage,
                            // the stroke needs to be reported for de-selection
                            if (null == strokesUnhit)
                            {
                                strokesUnhit = new StrokeCollection();
                            }
                            strokesUnhit.Add(strokeInfo.Stroke);
                        }
                    }
                }
            }

            _lasso.IsIncrementalLassoDirty = false;
            // Raise StrokesHitChanged event if any strokes has changed thier
            // hit status and there're the event subscribers.
            if ((null != strokesHit) || (null != strokesUnhit))
            {
                OnSelectionChanged(new LassoSelectionChangedEventArgs(strokesHit, strokesUnhit));
            }
        }
Ejemplo n.º 29
0
 /// <summary>Constructor</summary>
 internal StrokeCollectionChangedEventArgs(StrokeCollection added, StrokeCollection removed, int index) :
     this(added, removed)
 {
     _index = index;
 }
 public StrokeCollectionChangedEventArgs(StrokeCollection added, StrokeCollection removed)
 {
 }