Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / Ink / EraserBehavior.cs / 1305600 / EraserBehavior.cs
//---------------------------------------------------------------------------- // // File: EraserBehavior.cs // // Description: // ErasingBehavior for Ink // Features: // // History: // 3/15/2003 samgeo: Created // // Copyright (C) 2003 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Input; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Interop; using System.Windows.Navigation; using System.Windows.Media; using Swi = System.Windows.Ink; namespace MS.Internal.Ink { ////// Eraser Behavior /// internal sealed class EraserBehavior : StylusEditingBehavior { //------------------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------------------- #region Constructors internal EraserBehavior(EditingCoordinator editingCoordinator, InkCanvas inkCanvas) : base(editingCoordinator, inkCanvas) { } #endregion Constructors //-------------------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------------------- #region Protected Methods ////// Overrides SwitchToMode as the following expectations /// 19. From EraseByPoint To InkAndGesture /// After mode change ink is being collected. On StylusUp gesture event fires. If it�s not a gesture, StrokeCollected event fires. /// 20. From EraseByPoint To GestureOnly /// After mode change ink is being collected. On StylusUp gesture event fires. Stroke gets removed on StylusUp even if it�s not a gesture. /// 21. From EraseByPoint To Ink /// Ink collection starts when changing the mode. /// 22. From EraseByPoint To EraseByStroke /// After mode change StrokeErasing is performed. /// 23. From EraseByPoint To Select /// Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected. /// 24. From EraseByPoint To None /// No erasing is performed after mode change. /// 25. From EraseByStroke To InkAndGesture /// After mode change ink is being collected. On StylusUp gesture event fires. If it�s not a gesture, StrokeCollected event fires. /// 26. From EraseByStroke To GestureOnly /// After mode change ink is being collected. On StylusUp gesture event fires. Stroke gets removed on StylusUp even if it�s not a gesture. /// 27. From EraseByStroke To EraseByPoint /// After mode change PointErasing is performed. /// 28. From EraseByStroke To Ink /// Ink collection starts when changing the mode. /// 29. From EraseByStroke To Select /// Lasso is drawn for all packets between StylusDown and StylusUp. Strokes/elements within the lasso will be selected /// 30. From EraseByStroke To None /// No erasing is performed after mode change. /// /// protected override void OnSwitchToMode(InkCanvasEditingMode mode) { Debug.Assert(EditingCoordinator.IsInMidStroke, "SwitchToMode should only be called in a mid-stroke"); switch ( mode ) { case InkCanvasEditingMode.Ink: case InkCanvasEditingMode.InkAndGesture: case InkCanvasEditingMode.GestureOnly: { // Commit the current behavior Commit(true); // Change the mode. The dynamic renderer will be reset automatically. EditingCoordinator.ChangeStylusEditingMode(this, mode); break; } case InkCanvasEditingMode.EraseByPoint: case InkCanvasEditingMode.EraseByStroke: { Debug.Assert(_cachedEraseMode != mode); // Commit the current behavior Commit(true); // Change the mode EditingCoordinator.ChangeStylusEditingMode(this, mode); break; } case InkCanvasEditingMode.Select: { // Make a copy of the current cached points. StylusPointCollection cachedPoints = _stylusPoints != null ? _stylusPoints.Clone() : null; // Commit the current behavior. Commit(true); // Change the Select mode IStylusEditing newBehavior = EditingCoordinator.ChangeStylusEditingMode(this, mode); if ( cachedPoints != null // NOTICE-2006/04/27-WAYNEZEN, // EditingCoordinator.ChangeStylusEditingMode raises external event. // The user code could take any arbitrary action for instance calling InkCanvas.ReleaseMouseCapture() // So there is no guarantee that we could receive the newBehavior. && newBehavior != null ) { // Now add the previous points to the lasso behavior newBehavior.AddStylusPoints(cachedPoints, false/*userInitiated*/); } break; } case InkCanvasEditingMode.None: { // Discard the collected ink. Commit(true); // Change to the None mode EditingCoordinator.ChangeStylusEditingMode(this, mode); break; } default: Debug.Assert(false, "Unknown InkCanvasEditingMode!"); break; } } protected override void OnActivate() { base.OnActivate(); InkCanvasEditingMode newEraseMode = EditingCoordinator.ActiveEditingMode; Debug.Assert(newEraseMode == InkCanvasEditingMode.EraseByPoint || newEraseMode == InkCanvasEditingMode.EraseByStroke); // Check whether we have to update cursor. if ( _cachedEraseMode != newEraseMode ) { // EraseMode is changed _cachedEraseMode = newEraseMode; EditingCoordinator.InvalidateBehaviorCursor(this); } else if ( newEraseMode == InkCanvasEditingMode.EraseByPoint ) { // Invalidate the PointEraser if we don't have the cache yet. bool isPointEraserCursorValid = _cachedStylusShape != null; // NTRAID:WINDOWSOS#1673398-2006/05/23-WAYNEZEN, // If the cached EraserShape is different from the current EraserShape, we shoud just reset the cache. // The new cursor will be generated when it's needed later. if ( isPointEraserCursorValid && ( _cachedStylusShape.Width != InkCanvas.EraserShape.Width || _cachedStylusShape.Height != InkCanvas.EraserShape.Height || _cachedStylusShape.Rotation != InkCanvas.EraserShape.Rotation || _cachedStylusShape.GetType() != InkCanvas.EraserShape.GetType()) ) { Debug.Assert(_cachedPointEraserCursor != null, "_cachedPointEraserCursor shouldn't be null."); ResetCachedPointEraserCursor(); isPointEraserCursorValid = false; } if ( !isPointEraserCursorValid ) { // EraserShape is changed when the new mode is EraseByPoint EditingCoordinator.InvalidateBehaviorCursor(this); } } } ////// StylusInputBegin /// /// stylusPoints /// true if the source eventArgs.UserInitiated flag was set to true protected override void StylusInputBegin(StylusPointCollection stylusPoints, bool userInitiated) { // // get a disposable dynamic hit-tester and add event handler // _incrementalStrokeHitTester = this.InkCanvas.Strokes.GetIncrementalStrokeHitTester(this.InkCanvas.EraserShape); if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode ) { _incrementalStrokeHitTester.StrokeHit += new StrokeHitEventHandler(OnPointEraseResultChanged); } else { //we're in stroke hit test mode _incrementalStrokeHitTester.StrokeHit += new StrokeHitEventHandler(OnStrokeEraseResultChanged); } _stylusPoints = new StylusPointCollection(stylusPoints.Description, 100); _stylusPoints.Add(stylusPoints); // // start erasing // _incrementalStrokeHitTester.AddPoints(stylusPoints); // NTRAID:WINDOWSOS#1642274-2006/05/10-WAYNEZEN, // Since InkCanvas will ignore the animated tranforms when it receives the property changes. // So we should update our cursor when the stylus is down if there are animated transforms applied to InkCanvas. if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode ) { // Call InvalidateBehaviorCursor at the end of the routine. The method will cause an external event fired. // So it should be invoked after we set up our states. EditingCoordinator.InvalidateBehaviorCursor(this); } } ////// StylusInputContinue /// /// stylusPoints /// true if the source eventArgs.UserInitiated flag was set to true protected override void StylusInputContinue(StylusPointCollection stylusPoints, bool userInitiated) { _stylusPoints.Add(stylusPoints); _incrementalStrokeHitTester.AddPoints(stylusPoints); } ////// StylusInputEnd /// /// commit protected override void StylusInputEnd(bool commit) { if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode ) { _incrementalStrokeHitTester.StrokeHit-= new StrokeHitEventHandler(OnPointEraseResultChanged); } else { //we're in stroke hit test mode _incrementalStrokeHitTester.StrokeHit -= new StrokeHitEventHandler(OnStrokeEraseResultChanged); } _stylusPoints = null; // NTRAID#T2-26868-2004/11/1-WAYNEZEN, // Don't forget ending the current incremental hit testing. _incrementalStrokeHitTester.EndHitTesting(); _incrementalStrokeHitTester = null; } ////// Get eraser cursor. /// ///protected override Cursor GetCurrentCursor() { if ( InkCanvasEditingMode.EraseByPoint == _cachedEraseMode ) { if ( _cachedPointEraserCursor == null ) { _cachedStylusShape = InkCanvas.EraserShape; // NTRAID-WINDOWS#1430638-2006/01/04-WAYNEZEN, // The eraser cursor should respect the InkCanvas' Transform properties as the pen tip. Matrix xf = GetElementTransformMatrix(); if ( !xf.IsIdentity ) { // Zero the offsets if the element's transform in invertable. // Otherwise fallback the matrix to the identity. if ( xf.HasInverse ) { xf.OffsetX = 0; xf.OffsetY = 0; } else { xf = Matrix.Identity; } } _cachedPointEraserCursor = PenCursorManager.GetPointEraserCursor(_cachedStylusShape, xf); } return _cachedPointEraserCursor; } else { return PenCursorManager.GetStrokeEraserCursor(); } } /// /// ApplyTransformToCursor /// protected override void OnTransformChanged() { // Reset the cached point eraser cursor. ResetCachedPointEraserCursor(); } #endregion Protected Methods //-------------------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------------------- #region Private Methods ////// Reset the cached point eraser cursor. /// private void ResetCachedPointEraserCursor() { _cachedPointEraserCursor = null; _cachedStylusShape = null; } ////// /// /// /// private void OnStrokeEraseResultChanged(object sender, StrokeHitEventArgs e) { Debug.Assert(null != e.HitStroke); bool fSucceeded = false; // The below code calls out StrokeErasing or StrokeErased event. // The out-side code could throw exception. // We use try/finally block to protect our status. try { InkCanvasStrokeErasingEventArgs args = new InkCanvasStrokeErasingEventArgs(e.HitStroke); this.InkCanvas.RaiseStrokeErasing(args); if ( !args.Cancel ) { // Erase only if the event wasn't cancelled InkCanvas.Strokes.Remove(e.HitStroke); this.InkCanvas.RaiseInkErased(); } fSucceeded = true; } finally { if ( !fSucceeded ) { // Abort the editing. Commit(false); } } } ////// /// /// /// private void OnPointEraseResultChanged(object sender, StrokeHitEventArgs e) { Debug.Assert(null != e.HitStroke, "e.HitStroke cannot be null"); bool fSucceeded = false; // The below code might call out StrokeErasing or StrokeErased event. // The out-side code could throw exception. // We use try/finally block to protect our status. try { InkCanvasStrokeErasingEventArgs args = new InkCanvasStrokeErasingEventArgs(e.HitStroke); this.InkCanvas.RaiseStrokeErasing(args); if ( !args.Cancel ) { // Erase only if the event wasn't cancelled StrokeCollection eraseResult = e.GetPointEraseResults(); Debug.Assert(eraseResult != null, "eraseResult cannot be null"); StrokeCollection strokesToReplace = new StrokeCollection(); strokesToReplace.Add(e.HitStroke); try { // replace or remove the stroke if (eraseResult.Count > 0) { this.InkCanvas.Strokes.Replace(strokesToReplace, eraseResult); } else { this.InkCanvas.Strokes.Remove(strokesToReplace); } } catch (ArgumentException ex) { //this can happen if someone sits in an event handler //for StrokeErasing and removes the stroke. //this to harden against failure here. if (!ex.Data.Contains("System.Windows.Ink.StrokeCollection")) { //System.Windows.Ink.StrokeCollection didn't throw this, //we need to just throw the original exception throw; } } //raise ink erased this.InkCanvas.RaiseInkErased(); } fSucceeded = true; } finally { if ( !fSucceeded ) { // Abort the editing. Commit(false); } } } #endregion Private Methods //------------------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------------------- #region Private Fields private InkCanvasEditingMode _cachedEraseMode; private IncrementalStrokeHitTester _incrementalStrokeHitTester; private Cursor _cachedPointEraserCursor; private StylusShape _cachedStylusShape; private StylusPointCollection _stylusPoints = null; #endregion Private Fields } } // 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
- ConfigXmlElement.cs
- path.cs
- MediaPlayer.cs
- DBParameter.cs
- HttpProtocolImporter.cs
- StatusStrip.cs
- XmlBinaryWriter.cs
- ToolStripLabel.cs
- SymbolType.cs
- PropertyChangingEventArgs.cs
- CustomAttributeFormatException.cs
- SHA256.cs
- DbParameterHelper.cs
- TextSchema.cs
- TextTreeNode.cs
- GeometryDrawing.cs
- Span.cs
- IISUnsafeMethods.cs
- JournalEntryListConverter.cs
- XmlSchemaAnnotated.cs
- DesignTimeTemplateParser.cs
- FileAuthorizationModule.cs
- HybridObjectCache.cs
- Lazy.cs
- ParameterDataSourceExpression.cs
- LineVisual.cs
- IsolatedStorageException.cs
- XPathNodeIterator.cs
- Int16Animation.cs
- SqlCacheDependencyDatabaseCollection.cs
- DataControlButton.cs
- EmptyCollection.cs
- EntityConnection.cs
- SignatureSummaryDialog.cs
- SystemColorTracker.cs
- LayoutManager.cs
- CultureInfo.cs
- KnownBoxes.cs
- ArrayHelper.cs
- ControlAdapter.cs
- EnumerableCollectionView.cs
- _AuthenticationState.cs
- ManipulationStartingEventArgs.cs
- _SingleItemRequestCache.cs
- RoleManagerSection.cs
- SynchronizedInputPattern.cs
- SystemColors.cs
- TraceUtils.cs
- ValidationErrorEventArgs.cs
- BindingExpressionBase.cs
- WindowsListView.cs
- NavigationWindowAutomationPeer.cs
- InfoCardKeyedHashAlgorithm.cs
- EventDescriptor.cs
- SqlDelegatedTransaction.cs
- SqlDeflator.cs
- DetailsViewInsertedEventArgs.cs
- DependentTransaction.cs
- ClientFormsAuthenticationCredentials.cs
- TransformerInfoCollection.cs
- ObjectQueryState.cs
- NativeMethodsOther.cs
- CodeMemberEvent.cs
- TargetControlTypeAttribute.cs
- CommonProperties.cs
- ComboBoxItem.cs
- TiffBitmapDecoder.cs
- IdnElement.cs
- PersistenceTypeAttribute.cs
- NetworkAddressChange.cs
- SqlRowUpdatingEvent.cs
- TraceHandlerErrorFormatter.cs
- MailHeaderInfo.cs
- EditBehavior.cs
- Classification.cs
- Pkcs7Recipient.cs
- PathFigure.cs
- Unit.cs
- rsa.cs
- NetCodeGroup.cs
- SocketInformation.cs
- ReferencedAssembly.cs
- NullableDoubleMinMaxAggregationOperator.cs
- TextSerializer.cs
- BoundField.cs
- DbConnectionStringBuilder.cs
- DynamicRendererThreadManager.cs
- NameSpaceEvent.cs
- TrackingAnnotationCollection.cs
- PlanCompiler.cs
- EventWaitHandleSecurity.cs
- TreeNodeStyleCollection.cs
- PropertyInfoSet.cs
- MultilineStringEditor.cs
- ProfileGroupSettingsCollection.cs
- cookiecollection.cs
- Properties.cs
- PropertyToken.cs
- ReadOnlyObservableCollection.cs
- AuthorizationRuleCollection.cs