Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / MS / Internal / Controls / InkCanvasSelectionAdorner.cs / 1 / InkCanvasSelectionAdorner.cs
//---------------------------------------------------------------------------- // // File: InkCanvasSelectionAdorner.cs // // Description: // A class which is used as the selection adorner of the InkCanvas selection // // Features: // // History: // 1/27/2005 [....]: Created // // Copyright (C) 2001 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- //#define DEBUG_OUTPUT using MS.Internal; using MS.Internal.Controls; using MS.Internal.Ink; using System; using System.Diagnostics; using System.Collections.Generic; using System.Collections; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; namespace MS.Internal.Controls { ////// InkCanvasSelectionAdorner /// internal class InkCanvasSelectionAdorner : Adorner { ////// Constructor /// /// The adorned InkCanvas internal InkCanvasSelectionAdorner(UIElement adornedElement) : base(adornedElement) { Debug.Assert(adornedElement is InkCanvasInnerCanvas, "InkCanvasSelectionAdorner only should be used by InkCanvas internally"); // Initialize the internal data. _adornerBorderPen = new Pen(Brushes.Black, 1.0); DoubleCollection dashes = new DoubleCollection( ); dashes.Add(4.5); dashes.Add(4.5); _adornerBorderPen.DashStyle = new DashStyle(dashes, 2.25); _adornerBorderPen.DashCap = PenLineCap.Flat; _adornerBorderPen.Freeze(); _adornerPenBrush = new Pen(new SolidColorBrush(Color.FromRgb(132, 146, 222)), 1); _adornerPenBrush.Freeze(); _adornerFillBrush = new LinearGradientBrush( Color.FromRgb(240, 242, 255), //start color Color.FromRgb(180, 207, 248), //end color 45f //angle ); _adornerFillBrush.Freeze(); // Create a hatch pen DrawingGroup hatchDG = new DrawingGroup( ); DrawingContext dc = null; try { dc = hatchDG.Open( ); dc.DrawRectangle( Brushes.Transparent, null, new Rect(0.0, 0.0, 1f, 1f)); Pen squareCapPen = new Pen(Brushes.Black, LineThickness); squareCapPen.StartLineCap = PenLineCap.Square; squareCapPen.EndLineCap = PenLineCap.Square; dc.DrawLine(squareCapPen, new Point(1f, 0f), new Point(0f, 1f)); } finally { if ( dc != null ) { dc.Close( ); } } hatchDG.Freeze(); DrawingBrush tileBrush = new DrawingBrush(hatchDG); tileBrush.TileMode = TileMode.Tile; tileBrush.Viewport = new Rect(0, 0, HatchBorderMargin, HatchBorderMargin); tileBrush.ViewportUnits = BrushMappingMode.Absolute; tileBrush.Freeze(); _hatchPen = new Pen(tileBrush, HatchBorderMargin); _hatchPen.Freeze(); _elementsBounds = new List(); _strokesBounds = Rect.Empty; } /// /// SelectionHandleHitTest /// /// ///internal InkCanvasSelectionHitResult SelectionHandleHitTest(Point point) { InkCanvasSelectionHitResult result = InkCanvasSelectionHitResult.None; Rect rectWireFrame = GetWireFrameRect(); if ( !rectWireFrame.IsEmpty ) { // Hit test on the grab handles first for ( InkCanvasSelectionHitResult hitResult = InkCanvasSelectionHitResult.TopLeft; hitResult <= InkCanvasSelectionHitResult.Left; hitResult++ ) { Rect toleranceRect; Rect visibleRect; GetHandleRect(hitResult, rectWireFrame, out visibleRect, out toleranceRect); if (toleranceRect.Contains(point)) { result = hitResult; break; } } // Now, check if we hit on the frame if ( result == InkCanvasSelectionHitResult.None ) { Rect outterRect = Rect.Inflate(rectWireFrame, CornerResizeHandleSize / 2, CornerResizeHandleSize / 2); if ( outterRect.Contains(point) ) { result = InkCanvasSelectionHitResult.Selection; // } } } return result; } /// /// Update the selection wire frame. /// Called by /// InkCanvasSelection.UpdateSelectionAdorner /// /// /// internal void UpdateSelectionWireFrame(Rect strokesBounds, ListhatchBounds) { bool isStrokeBoundsDifferent = false; bool isElementsBoundsDifferent = false; // Check if the strokes' bounds are changed. if ( _strokesBounds != strokesBounds ) { _strokesBounds = strokesBounds; isStrokeBoundsDifferent = true; } // Check if the elements' bounds are changed. int count = hatchBounds.Count; if ( count != _elementsBounds.Count ) { isElementsBoundsDifferent = true; } else { for ( int i = 0; i < count; i++ ) { if ( _elementsBounds[i] != hatchBounds[i] ) { isElementsBoundsDifferent = true; break; } } } if ( isStrokeBoundsDifferent || isElementsBoundsDifferent ) { if ( isElementsBoundsDifferent ) { _elementsBounds = hatchBounds; } // Invalidate our visual since the selection is changed. InvalidateVisual(); } } /// /// OnRender /// /// protected override void OnRender(DrawingContext drawingContext) { // Draw the background and hatch border around the elements DrawBackgound(drawingContext); // Draw the selection frame. Rect rectWireFrame = GetWireFrameRect(); if ( !rectWireFrame.IsEmpty ) { // Draw the wire frame. drawingContext.DrawRectangle(null, _adornerBorderPen, rectWireFrame); // Draw grab handles DrawHandles(drawingContext, rectWireFrame); } } ////// Draw Handles /// /// /// private void DrawHandles(DrawingContext drawingContext, Rect rectWireFrame) { for ( InkCanvasSelectionHitResult hitResult = InkCanvasSelectionHitResult.TopLeft; hitResult <= InkCanvasSelectionHitResult.Left; hitResult++ ) { // Draw the handle Rect toleranceRect; Rect visibleRect; GetHandleRect(hitResult, rectWireFrame, out visibleRect, out toleranceRect); drawingContext.DrawRectangle(_adornerFillBrush, _adornerPenBrush, visibleRect); } } ////// Draw the hatches and the transparent area where isn't covering the elements. /// /// private void DrawBackgound(DrawingContext drawingContext) { PathGeometry hatchGeometry = null; Geometry rectGeometry = null; int count = _elementsBounds.Count; if ( count != 0 ) { // Create a union collection of the element regions. for ( int i = 0; i < count; i++ ) { Rect hatchRect = _elementsBounds[i]; if ( hatchRect.IsEmpty ) { continue; } hatchRect.Inflate(HatchBorderMargin / 2, HatchBorderMargin / 2); if ( hatchGeometry == null ) { PathFigure path = new PathFigure(); path.StartPoint = new Point(hatchRect.Left, hatchRect.Top); PathSegmentCollection segments = new PathSegmentCollection(); PathSegment line = new LineSegment(new Point(hatchRect.Right, hatchRect.Top), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Right, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Top), true); line.Freeze(); segments.Add(line); segments.Freeze(); path.Segments = segments; path.IsClosed = true; path.Freeze(); hatchGeometry = new PathGeometry(); hatchGeometry.Figures.Add(path); } else { rectGeometry = new RectangleGeometry(hatchRect); rectGeometry.Freeze(); hatchGeometry = Geometry.Combine(hatchGeometry, rectGeometry, GeometryCombineMode.Union, null); } } } // Then, create a region which equals to "SelectionFrame - element1 bounds - element2 bounds - ..." GeometryGroup backgroundGeometry = new GeometryGroup( ); GeometryCollection geometryCollection = new GeometryCollection(); // Add the entile rectanlge to the group. rectGeometry = new RectangleGeometry(new Rect(0, 0, RenderSize.Width, RenderSize.Height)); rectGeometry.Freeze(); geometryCollection.Add(rectGeometry); // Add the union of the element rectangles. Then the group will do oddeven operation. Geometry outlineGeometry = null; if ( hatchGeometry != null ) { hatchGeometry.Freeze(); outlineGeometry = hatchGeometry.GetOutlinedPathGeometry(); outlineGeometry.Freeze(); if ( count == 1 && ((InkCanvasInnerCanvas)AdornedElement).InkCanvas.GetSelectedStrokes().Count == 0 ) { geometryCollection.Add(outlineGeometry); } } geometryCollection.Freeze(); backgroundGeometry.Children = geometryCollection; backgroundGeometry.Freeze(); // Then, draw the region which may contain holes so that the elements cannot be covered. // After that, the underneath elements can receive the messages. #if DEBUG_OUTPUT // Draw the debug feedback drawingContext.DrawGeometry(new SolidColorBrush(Color.FromArgb(128, 255, 255, 0)), null, backgroundGeometry); #else drawingContext.DrawGeometry(Brushes.Transparent, null, backgroundGeometry); #endif // At last, draw the hatch borders if ( outlineGeometry != null ) { drawingContext.DrawGeometry(null, _hatchPen, outlineGeometry); } } ////// Returns the handle rect (both visibile and the tolerance one) /// private void GetHandleRect(InkCanvasSelectionHitResult hitResult, Rect rectWireFrame, out Rect visibleRect, out Rect toleranceRect) { Point center = new Point(); double size = 0; double tolerance = ResizeHandleTolerance; switch ( hitResult ) { case InkCanvasSelectionHitResult.TopLeft: { size = CornerResizeHandleSize; center = new Point(rectWireFrame.Left, rectWireFrame.Top); break; } case InkCanvasSelectionHitResult.Top: { size = MiddleResizeHandleSize; center = new Point(rectWireFrame.Left + rectWireFrame.Width / 2, rectWireFrame.Top); tolerance = (CornerResizeHandleSize - MiddleResizeHandleSize) + ResizeHandleTolerance; break; } case InkCanvasSelectionHitResult.TopRight: { size = CornerResizeHandleSize; center = new Point(rectWireFrame.Right, rectWireFrame.Top); break; } case InkCanvasSelectionHitResult.Left: { size = MiddleResizeHandleSize; center = new Point(rectWireFrame.Left, rectWireFrame.Top + rectWireFrame.Height / 2); tolerance = (CornerResizeHandleSize - MiddleResizeHandleSize) + ResizeHandleTolerance; break; } case InkCanvasSelectionHitResult.Right: { size = MiddleResizeHandleSize; center = new Point(rectWireFrame.Right, rectWireFrame.Top + rectWireFrame.Height / 2); tolerance = (CornerResizeHandleSize - MiddleResizeHandleSize) + ResizeHandleTolerance; break; } case InkCanvasSelectionHitResult.BottomLeft: { size = CornerResizeHandleSize; center = new Point(rectWireFrame.Left, rectWireFrame.Bottom); break; } case InkCanvasSelectionHitResult.Bottom: { size = MiddleResizeHandleSize; center = new Point(rectWireFrame.Left + rectWireFrame.Width / 2, rectWireFrame.Bottom); tolerance = (CornerResizeHandleSize - MiddleResizeHandleSize) + ResizeHandleTolerance; break; } case InkCanvasSelectionHitResult.BottomRight: { size = CornerResizeHandleSize; center = new Point(rectWireFrame.Right, rectWireFrame.Bottom); break; } } visibleRect = new Rect(center.X - size / 2, center.Y - size / 2, size, size); toleranceRect = visibleRect; toleranceRect.Inflate(tolerance, tolerance); } ////// Returns the wire frame bounds which crosses the center of the selection handles /// ///private Rect GetWireFrameRect() { Rect frameRect = Rect.Empty; Rect selectionRect = ((InkCanvasInnerCanvas)AdornedElement).InkCanvas.GetSelectionBounds(); if ( !selectionRect.IsEmpty ) { frameRect = Rect.Inflate(selectionRect, BorderMargin, BorderMargin); } return frameRect; } private Pen _adornerBorderPen; private Pen _adornerPenBrush; private Brush _adornerFillBrush; private Pen _hatchPen; private Rect _strokesBounds; private List _elementsBounds; // The buffer around the outside of this element private const double BorderMargin = HatchBorderMargin + 2f; private const double HatchBorderMargin = 6f; // Constants for Resize handles. private const int CornerResizeHandleSize = 8; private const int MiddleResizeHandleSize = 6; private const double ResizeHandleTolerance = 3d; private const double LineThickness = 0.16; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- VideoDrawing.cs
- MonthChangedEventArgs.cs
- BitmapFrameEncode.cs
- ButtonChrome.cs
- XmlChildEnumerator.cs
- CheckBox.cs
- SafeProcessHandle.cs
- ActiveXSite.cs
- PixelShader.cs
- BaseComponentEditor.cs
- FacetDescriptionElement.cs
- GuidTagList.cs
- VectorValueSerializer.cs
- GeneralTransform3DGroup.cs
- DbConnectionPoolGroupProviderInfo.cs
- TimeZone.cs
- StopStoryboard.cs
- OverrideMode.cs
- EncodingFallbackAwareXmlTextWriter.cs
- KnownAssembliesSet.cs
- DataPagerFieldCollection.cs
- WebPartDisplayModeEventArgs.cs
- DataGridViewHeaderCell.cs
- OutputCacheProfileCollection.cs
- ParameterCollectionEditor.cs
- BaseTemplateParser.cs
- ViewSimplifier.cs
- CodeDirectionExpression.cs
- BamlCollectionHolder.cs
- HwndSubclass.cs
- BaseAddressElement.cs
- Nullable.cs
- AsmxEndpointPickerExtension.cs
- Geometry.cs
- Border.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- ProvidePropertyAttribute.cs
- AttributeCollection.cs
- BaseDataBoundControl.cs
- MouseCaptureWithinProperty.cs
- CustomAssemblyResolver.cs
- DesignerTextWriter.cs
- ProgressBarAutomationPeer.cs
- HorizontalAlignConverter.cs
- ProviderCommandInfoUtils.cs
- CryptoApi.cs
- CacheDict.cs
- AtomContentProperty.cs
- DataGridViewColumnDesignTimeVisibleAttribute.cs
- SettingsContext.cs
- IndicCharClassifier.cs
- TreeBuilder.cs
- ValidationError.cs
- IncrementalHitTester.cs
- TemplateBuilder.cs
- EntityTemplateFactory.cs
- ConfigurationLoaderException.cs
- XpsImage.cs
- _NetworkingPerfCounters.cs
- FillErrorEventArgs.cs
- FrameworkObject.cs
- InputReferenceExpression.cs
- AstTree.cs
- XmlText.cs
- SafeCoTaskMem.cs
- OleDbDataAdapter.cs
- OdbcRowUpdatingEvent.cs
- RemoteWebConfigurationHostServer.cs
- DoubleLink.cs
- RecognizerStateChangedEventArgs.cs
- IntSecurity.cs
- EncryptedPackage.cs
- Utils.cs
- SystemFonts.cs
- SynchronizationLockException.cs
- GeneralTransformGroup.cs
- XmlWellformedWriter.cs
- ConfigurationSectionHelper.cs
- SQLBinaryStorage.cs
- MouseBinding.cs
- ProxyWebPartManagerDesigner.cs
- StrokeNodeOperations.cs
- SqlStream.cs
- WebPartDisplayModeEventArgs.cs
- KeySpline.cs
- FacetEnabledSchemaElement.cs
- ScrollChrome.cs
- EditBehavior.cs
- FrameworkObject.cs
- CompositeFontFamily.cs
- GridLength.cs
- RepeaterItem.cs
- DataGridItemAutomationPeer.cs
- ColorAnimation.cs
- SettingsBase.cs
- MailMessageEventArgs.cs
- FileIOPermission.cs
- TargetPerspective.cs
- PropertyEntry.cs
- CodePageEncoding.cs