Esempio n. 1
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));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Hit tests all segments within the lasso loops
        /// </summary>
        /// <returns> a StrokeIntersection array for these segments</returns>
        internal StrokeIntersection[] HitTest(Lasso lasso)
        {
            // Check the input parameters
            System.Diagnostics.Debug.Assert(lasso != null);
            if (lasso.IsEmpty)
            {
                return new StrokeIntersection[0];
            }

            // The following will check whether all the points are within the lasso.
            // If yes, return the whole stroke as being hit.
            if (!lasso.Bounds.IntersectsWith(this.GetBounds()))
            {
                return new StrokeIntersection[0];
            }
            return lasso.HitTest(StrokeNodeIterator.GetIterator(this, this.DrawingAttributes));
        }