/// <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); } }
/// <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); }
/// <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); } }
/// <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(); }
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; }
/// <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); }); } }
private void Strokes_StrokesChanged(object sender, System.Windows.Ink.StrokeCollectionChangedEventArgs e) { if (handle) { _added = e.Added; _removed = e.Removed; testiadded.Add(_added); } }
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); }
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); }
/// <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; }
//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; } }
/// <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); }
/// <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)); }
/// <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); }
/// <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]); }
/// <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]); }
/// <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); }
internal LassoSelectionChangedEventArgs(StrokeCollection selectedStrokes, StrokeCollection deselectedStrokes) { _selectedStrokes = selectedStrokes; _deselectedStrokes = deselectedStrokes; }
internal ReadOnlyCollection <GestureRecognitionResult> CriticalRecognize(StrokeCollection strokes) { return(RecognizeImpl(strokes)); }
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>)); }
/// <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)); }
/// <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); }
/// <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)); } }
/// <summary>Constructor</summary> internal StrokeCollectionChangedEventArgs(StrokeCollection added, StrokeCollection removed, int index) : this(added, removed) { _index = index; }
public StrokeCollectionChangedEventArgs(StrokeCollection added, StrokeCollection removed) { }