Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Ink / StrokeCollection2.cs / 1 / StrokeCollection2.cs
//------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------- using MS.Utility; using System; using System.ComponentModel; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows.Media; using System.Windows.Input; using MS.Internal; using MS.Internal.Ink; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Ink { ////// The hit-testing API of StrokeCollection. /// public partial class StrokeCollection : Collection, INotifyPropertyChanged, INotifyCollectionChanged { #region Public APIs /// /// Calculates the combined bounds of all strokes in the collection /// ///public Rect GetBounds() { Rect bounds = Rect.Empty; foreach (Stroke stroke in this) { // [....] - 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 bounds.Union(stroke.GetBounds()); #pragma warning restore 1634, 1691 } return bounds; } // /// /// Tap-hit. Hit tests all strokes within a point, and returns a StrokeCollection for these strokes.Internally does Stroke.HitTest(Point, 1pxlRectShape). /// ///A StrokeCollection that either empty or contains the top hit stroke public StrokeCollection HitTest(Point point) { return PointHitTest(point, new RectangleStylusShape(1f, 1f)); } ////// Tap-hit /// /// The central point /// The diameter value of the circle ///A StrokeCollection that either empty or contains the top hit stroke public StrokeCollection HitTest(Point point, double diameter) { if (Double.IsNaN(diameter) || diameter < DrawingAttributes.MinWidth || diameter > DrawingAttributes.MaxWidth) { throw new ArgumentOutOfRangeException("diameter", SR.Get(SRID.InvalidDiameter)); } return PointHitTest(point, new EllipseStylusShape(diameter, diameter)); } ////// Hit-testing with lasso /// /// points making the lasso /// the margin value to tell whether a stroke /// is in or outside of the rect ///collection of strokes found inside the rectangle public StrokeCollection HitTest(IEnumerablelassoPoints, 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; } /// /// Hit-testing with rectangle /// /// hitting rectangle /// the percentage of the stroke that must be within /// the bounds to be considered hit ///collection of strokes found inside the rectangle public StrokeCollection HitTest(Rect bounds, int percentageWithinBounds) { // Check the input parameters if ((percentageWithinBounds < 0) || (percentageWithinBounds > 100)) { throw new System.ArgumentOutOfRangeException("percentageWithinBounds"); } if (bounds.IsEmpty) { return new StrokeCollection(); } // Enumerate thru the strokes collect those found within the rectangle. StrokeCollection hits = new StrokeCollection(); foreach (Stroke stroke in this) { // [....] - 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 (true == stroke.HitTest(bounds, percentageWithinBounds)) { hits.Add(stroke); } #pragma warning restore 1634, 1691 } return hits; } ////// Issue: what's the return value /// /// /// ///public StrokeCollection HitTest(IEnumerable 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) { // [....] - 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; } /// /// Clips out all ink outside a given lasso /// /// lasso public void Clip(IEnumerablelassoPoints) { // 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); } } /// /// Clips out all ink outside a given rectangle. /// /// rectangle to clip with public void Clip(Rect bounds) { if (bounds.IsEmpty == false) { Clip(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft }); } } ////// Erases all ink inside a lasso /// /// lasso to erase within public void Erase(IEnumerablelassoPoints) { // 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) { return; } Lasso lasso = new SingleLoopLasso(); lasso.AddPoints(lassoPoints); for (int i = 0; i < this.Count; i++) { Stroke stroke = this[i]; StrokeCollection eraseResult = stroke.Erase(stroke.HitTest(lasso)); UpdateStrokeCollection(stroke, eraseResult, ref i); } } /// /// Erases all ink inside a given rectangle /// /// rectangle to erase within public void Erase(Rect bounds) { if (bounds.IsEmpty == false) { Erase(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft }); } } ////// Erases all ink hit by the contour of an erasing stroke /// /// Shape of the eraser /// a path making the spine of the erasing stroke public void Erase(IEnumerableeraserPath, StylusShape eraserShape) { // Check the input parameters if (eraserShape == null) { throw new System.ArgumentNullException(SR.Get(SRID.SCEraseShape)); } if (eraserPath == null) { throw new System.ArgumentNullException(SR.Get(SRID.SCErasePath)); } if (IEnumerablePointHelper.GetCount(eraserPath) == 0) { return; } ErasingStroke erasingStroke = new ErasingStroke(eraserShape, eraserPath); for (int i = 0; i < this.Count; i++) { Stroke stroke = this[i]; List intersections = new List (); erasingStroke.EraseTest(StrokeNodeIterator.GetIterator(stroke, stroke.DrawingAttributes), intersections); StrokeCollection eraseResult = stroke.Erase(intersections.ToArray()); UpdateStrokeCollection(stroke, eraseResult, ref i); } } /// /// Render the StrokeCollection under the specified DrawingContext. /// /// public void Draw(DrawingContext context) { if (null == context) { throw new System.ArgumentNullException("context"); } //The verification of UI context affinity is done in Stroke.Draw() ListsolidStrokes = new List (); Dictionary > highLighters = new Dictionary >(); for (int i = 0; i < this.Count; i++) { Stroke stroke = this[i]; List strokes; if (stroke.DrawingAttributes.IsHighlighter) { // It's very important to override the Alpha value so that Colors of the same RGB vale // but different Alpha would be in the same list. Color color = StrokeRenderer.GetHighlighterColor(stroke.DrawingAttributes.Color); if (highLighters.TryGetValue(color, out strokes) == false) { strokes = new List (); highLighters.Add(color, strokes); } strokes.Add(stroke); } else { solidStrokes.Add(stroke); } } foreach (List strokes in highLighters.Values) { context.PushOpacity(StrokeRenderer.HighlighterOpacity); try { foreach (Stroke stroke in strokes) { stroke.DrawInternal(context, StrokeRenderer.GetHighlighterAttributes(stroke, stroke.DrawingAttributes), false /*Don't draw selected stroke as hollow*/); } } finally { context.Pop(); } } foreach(Stroke stroke in solidStrokes) { stroke.DrawInternal(context, stroke.DrawingAttributes, false/*Don't draw selected stroke as hollow*/); } } #endregion #region Incremental hit-testing /// /// Creates an incremental hit-tester for hit-testing with a shape. /// Scenarios: stroke-erasing and point-erasing /// /// shape of the eraser ///an instance of IncrementalStrokeHitTester public IncrementalStrokeHitTester GetIncrementalStrokeHitTester(StylusShape eraserShape) { if (eraserShape == null) { throw new System.ArgumentNullException("eraserShape"); } return new IncrementalStrokeHitTester(this, eraserShape); } ////// Creates an incremental hit-tester for selecting with lasso. /// /// The percentage of the stroke that must be within the lasso to be considered hit ///an instance of incremental hit-tester public IncrementalLassoHitTester GetIncrementalLassoHitTester(int percentageWithinLasso) { if ((percentageWithinLasso < 0) || (percentageWithinLasso > 100)) { throw new System.ArgumentOutOfRangeException("percentageWithinLasso"); } return new IncrementalLassoHitTester(this, percentageWithinLasso); } #endregion ////// Return all hit strokes that the StylusShape intersects and returns them in a StrokeCollection /// private StrokeCollection PointHitTest(Point point, StylusShape shape) { // Create the collection to return StrokeCollection hits = new StrokeCollection(); for (int i = 0; i < this.Count; i++) { Stroke stroke = this[i]; if (stroke.HitTest(new Point[] { point }, shape)) { hits.Add(stroke); } } return hits; } private void UpdateStrokeCollection(Stroke original, StrokeCollection toReplace, ref int index) { System.Diagnostics.Debug.Assert(original != null && toReplace != null); System.Diagnostics.Debug.Assert(index >= 0 && index < this.Count); if (toReplace.Count == 0) { Remove(original); index--; } else if (!(toReplace.Count == 1 && toReplace[0] == original)) { Replace(original, toReplace); // Update the current index index += toReplace.Count - 1; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- _LocalDataStore.cs
- DefaultBinder.cs
- IndexOutOfRangeException.cs
- SessionStateSection.cs
- CompilerTypeWithParams.cs
- TypeSystem.cs
- RuleDefinitions.cs
- RSAProtectedConfigurationProvider.cs
- EventLogLink.cs
- PolyLineSegment.cs
- WindowsRegion.cs
- SimpleFieldTemplateFactory.cs
- Utility.cs
- ConfigurationErrorsException.cs
- HandlerFactoryWrapper.cs
- OdbcUtils.cs
- DetailsViewRow.cs
- FixUpCollection.cs
- CompensationDesigner.cs
- PropertyDescriptorGridEntry.cs
- CharacterMetrics.cs
- XmlText.cs
- ToolStripRenderer.cs
- CodeDefaultValueExpression.cs
- MetabaseReader.cs
- MsmqActivation.cs
- LinqDataSourceInsertEventArgs.cs
- Descriptor.cs
- WasEndpointConfigContainer.cs
- XPathNavigator.cs
- FaultReasonText.cs
- ScriptDescriptor.cs
- EntityViewGenerator.cs
- AuthStoreRoleProvider.cs
- RadioButtonFlatAdapter.cs
- WebSysDisplayNameAttribute.cs
- XmlWhitespace.cs
- _KerberosClient.cs
- WebPartMenu.cs
- CompilationRelaxations.cs
- cookiecollection.cs
- AdapterUtil.cs
- PageBreakRecord.cs
- RegistryPermission.cs
- EventRoute.cs
- DataTableTypeConverter.cs
- FormsAuthenticationConfiguration.cs
- ReferencedAssembly.cs
- Suspend.cs
- AuthenticationModuleElementCollection.cs
- Oci.cs
- BrowserDefinitionCollection.cs
- DragDeltaEventArgs.cs
- DataGridRow.cs
- NavigationProperty.cs
- SaveFileDialogDesigner.cs
- EventLogStatus.cs
- MobileTextWriter.cs
- ProjectionNode.cs
- PerformanceCounterCategory.cs
- PenCursorManager.cs
- CodeNamespace.cs
- FilterEventArgs.cs
- __Filters.cs
- ObjectView.cs
- WebBaseEventKeyComparer.cs
- WrappedReader.cs
- SkipStoryboardToFill.cs
- CompilationLock.cs
- ValueExpressions.cs
- WebPartUtil.cs
- WrapperSecurityCommunicationObject.cs
- MenuAutomationPeer.cs
- BooleanKeyFrameCollection.cs
- GZipStream.cs
- util.cs
- NodeLabelEditEvent.cs
- XmlSchemaSubstitutionGroup.cs
- WorkflowMarkupSerializationProvider.cs
- AdCreatedEventArgs.cs
- DataGridTableStyleMappingNameEditor.cs
- EntityAdapter.cs
- DependencyObjectValidator.cs
- CrossSiteScriptingValidation.cs
- TextEffectCollection.cs
- PropertyReferenceSerializer.cs
- WindowsSecurityToken.cs
- KnownTypesHelper.cs
- Token.cs
- Camera.cs
- FloatMinMaxAggregationOperator.cs
- SortKey.cs
- TextRangeAdaptor.cs
- ServiceHostingEnvironment.cs
- RSAOAEPKeyExchangeDeformatter.cs
- ImageAnimator.cs
- SystemIPGlobalStatistics.cs
- GridErrorDlg.cs
- XmlNavigatorFilter.cs
- Int64KeyFrameCollection.cs