Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Documents / TextSelectionHighlightLayer.cs / 1 / TextSelectionHighlightLayer.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: Highlight rendering for the TextSelection. // // History: // 07/01/2004 : benwest - Created // //--------------------------------------------------------------------------- using System; using MS.Internal; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; namespace System.Windows.Documents { // Highlight rendering for the TextSelection. internal class TextSelectionHighlightLayer : HighlightLayer { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors // Static constructor. static TextSelectionHighlightLayer() { _selectedValue = new object(); } // Constructor. internal TextSelectionHighlightLayer(ITextSelection selection) { _selection = selection; _selection.Changed += new EventHandler(OnSelectionChanged); _oldStart = _selection.Start; _oldEnd = _selection.End; } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods // Returns the value of a property stored on scoping highlight, if any. // // If no property value is set, returns DependencyProperty.UnsetValue. internal override object GetHighlightValue(StaticTextPointer textPosition, LogicalDirection direction) { object value; if (IsContentHighlighted(textPosition, direction)) { value = _selectedValue; } else { value = DependencyProperty.UnsetValue; } return value; } // Returns true iff the indicated content has scoping highlights. internal override bool IsContentHighlighted(StaticTextPointer textPosition, LogicalDirection direction) { int segmentCount; TextSegment textSegment; // No highlight when the selection is for interim character. if (_selection.IsInterimSelection) { return false; } // Check all segments of selection ListtextSegments = _selection.TextSegments; segmentCount = textSegments.Count; for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) { textSegment = textSegments[segmentIndex]; if ((direction == LogicalDirection.Forward && textSegment.Start.CompareTo(textPosition) <= 0 && textPosition.CompareTo(textSegment.End) < 0) || // (direction == LogicalDirection.Backward && textSegment.Start.CompareTo(textPosition) < 0 && textPosition.CompareTo(textSegment.End) <= 0)) { return true; } } return false; } // Returns the position of the next highlight start or end in an // indicated direction, or null if there is no such position. internal override StaticTextPointer GetNextChangePosition(StaticTextPointer textPosition, LogicalDirection direction) { StaticTextPointer transitionPosition; transitionPosition = StaticTextPointer.Null; if (!IsTextRangeEmpty(_selection) && !_selection.IsInterimSelection) { int segmentCount; List textSegments = _selection.TextSegments; TextSegment textSegment; segmentCount = textSegments.Count; if (direction == LogicalDirection.Forward) { for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) { textSegment = textSegments[segmentIndex]; // Ignore empty segments. // if (textSegment.Start.CompareTo(textSegment.End) != 0) { if (textPosition.CompareTo(textSegment.Start) < 0) { transitionPosition = textSegment.Start.CreateStaticPointer(); break; } else if (textPosition.CompareTo(textSegment.End) < 0) { transitionPosition = textSegment.End.CreateStaticPointer(); break; } } } } else { for (int segmentIndex = segmentCount - 1; segmentIndex >= 0; segmentIndex--) { textSegment = textSegments[segmentIndex]; if (textSegment.Start.CompareTo(textSegment.End) != 0) { if (textPosition.CompareTo(textSegment.End) > 0) { transitionPosition = textSegment.End.CreateStaticPointer(); break; } else if (textPosition.CompareTo(textSegment.Start) > 0) { transitionPosition = textSegment.Start.CreateStaticPointer(); break; } } } } } return transitionPosition; } // This is actual implementation to make highlight change notification. // This is called when highlight needs to be changed without public TextSelection change event. internal void InternalOnSelectionChanged() { ITextPointer newStart; ITextPointer newEnd; ITextPointer invalidRangeLeftStart; ITextPointer invalidRangeLeftEnd; ITextPointer invalidRangeRightStart; ITextPointer invalidRangeRightEnd; TextSelectionHighlightChangedEventArgs args; // If the current seleciton is interim selection, we do not highlight it // and we make newStart == newEnd. if (!_selection.IsInterimSelection) { newStart = _selection.Start; } else { newStart = _selection.End; } newEnd = _selection.End; // We want to raise an event that tracks the change tightly -- // only identifying content where the selection status actually changed. // This is important for render performance. // // Ex: // Old selection: 012 345 678 // New selection: 0123456 78 // // Should raise (3-3), (6-6) as deltas, not (3-6). // // Get the left side invalid range. if (_oldStart.CompareTo(newStart) < 0) { invalidRangeLeftStart = _oldStart; invalidRangeLeftEnd = TextPointerBase.Min(newStart, _oldEnd); } else { invalidRangeLeftStart = newStart; invalidRangeLeftEnd = TextPointerBase.Min(newEnd, _oldStart); } // Get the right side invalid range. if (_oldEnd.CompareTo(newEnd) < 0) { invalidRangeRightStart = TextPointerBase.Max(newStart, _oldEnd); invalidRangeRightEnd = newEnd; } else { invalidRangeRightStart = TextPointerBase.Max(newEnd, _oldStart); invalidRangeRightEnd = _oldEnd; } _oldStart = newStart; _oldEnd = newEnd; if (this.Changed != null) { if (invalidRangeLeftStart.CompareTo(invalidRangeLeftEnd) != 0 || invalidRangeRightStart.CompareTo(invalidRangeRightEnd) != 0) { args = new TextSelectionHighlightChangedEventArgs(invalidRangeLeftStart, invalidRangeLeftEnd, invalidRangeRightStart, invalidRangeRightEnd); this.Changed(this, args); } } } #endregion Internal Methods //------------------------------------------------------ // // Internal Properties // //------------------------------------------------------ #region Internal Properties ////// Type identifying this layer for Highlights.GetHighlightValue calls. /// internal override Type OwnerType { get { return typeof(TextSelection); } } #endregion Internal Properties //----------------------------------------------------- // // Internal Events // //------------------------------------------------------ #region Internal Events // Event raised when a highlight range is inserted, removed, moved, or // has a local property value change. internal override event HighlightChangedEventHandler Changed; #endregion Internal Events //----------------------------------------------------- // // Private Methods // //----------------------------------------------------- #region Private Methods // Callback for TextSelection.Moved event. // We use this event to trigger highlight change notifications. private void OnSelectionChanged(object sender, EventArgs e) { Invariant.Assert(_selection == (ITextSelection)sender); // text container and password text container are utilizing the new selection // that does not rely on text selection event. this is a performance optimization. object textContainer = _selection.Start.TextContainer; if ( textContainer is TextContainer || textContainer is System.Windows.Controls.PasswordTextContainer ) { return; } InternalOnSelectionChanged(); } // Check the text range whether it is empty or not without normalization. private bool IsTextRangeEmpty(ITextRange textRange) { // We assume that TextRange.TextSegments property getter does not normalize a range, // thus we can avoid re-entrancy. Invariant.Assert(textRange._TextSegments.Count > 0); return textRange._TextSegments[0].Start.CompareTo(textRange._TextSegments[textRange._TextSegments.Count - 1].End) == 0; } #endregion Private Methods //----------------------------------------------------- // // Private Types // //------------------------------------------------------ #region Private Types // Argument for the Changed event, encapsulates a highlight change. private class TextSelectionHighlightChangedEventArgs : HighlightChangedEventArgs { // Constructor. internal TextSelectionHighlightChangedEventArgs(ITextPointer invalidRangeLeftStart, ITextPointer invalidRangeLeftEnd, ITextPointer invalidRangeRightStart, ITextPointer invalidRangeRightEnd) { ListrangeArray; Invariant.Assert(invalidRangeLeftStart != invalidRangeLeftEnd || invalidRangeRightStart != invalidRangeRightEnd, "Unexpected empty range!"); if (invalidRangeLeftStart.CompareTo(invalidRangeLeftEnd) == 0) { rangeArray = new List (1); rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd)); } else if (invalidRangeRightStart.CompareTo(invalidRangeRightEnd) == 0) { rangeArray = new List (1); rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd)); } else { rangeArray = new List (2); rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd)); rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd)); } _ranges = new ReadOnlyCollection (rangeArray); } // Collection of changed content ranges. internal override IList Ranges { get { return _ranges; } } // Type identifying the owner of the changed layer. internal override Type OwnerType { get { return typeof(TextSelection); } } // Collection of changed content ranges. private readonly ReadOnlyCollection _ranges; } #endregion Private Types //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ #region Private Fields // TextSelection associated with this layer. private readonly ITextSelection _selection; // Previous position of the TextSelection, used to calculate deltas // on TextSelection.Moved events. private ITextPointer _oldStart; private ITextPointer _oldEnd; // Sentinel object used to tag highlights. private static readonly object _selectedValue; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // // Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: Highlight rendering for the TextSelection. // // History: // 07/01/2004 : benwest - Created // //--------------------------------------------------------------------------- using System; using MS.Internal; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; namespace System.Windows.Documents { // Highlight rendering for the TextSelection. internal class TextSelectionHighlightLayer : HighlightLayer { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors // Static constructor. static TextSelectionHighlightLayer() { _selectedValue = new object(); } // Constructor. internal TextSelectionHighlightLayer(ITextSelection selection) { _selection = selection; _selection.Changed += new EventHandler(OnSelectionChanged); _oldStart = _selection.Start; _oldEnd = _selection.End; } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods // Returns the value of a property stored on scoping highlight, if any. // // If no property value is set, returns DependencyProperty.UnsetValue. internal override object GetHighlightValue(StaticTextPointer textPosition, LogicalDirection direction) { object value; if (IsContentHighlighted(textPosition, direction)) { value = _selectedValue; } else { value = DependencyProperty.UnsetValue; } return value; } // Returns true iff the indicated content has scoping highlights. internal override bool IsContentHighlighted(StaticTextPointer textPosition, LogicalDirection direction) { int segmentCount; TextSegment textSegment; // No highlight when the selection is for interim character. if (_selection.IsInterimSelection) { return false; } // Check all segments of selection ListtextSegments = _selection.TextSegments; segmentCount = textSegments.Count; for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) { textSegment = textSegments[segmentIndex]; if ((direction == LogicalDirection.Forward && textSegment.Start.CompareTo(textPosition) <= 0 && textPosition.CompareTo(textSegment.End) < 0) || // (direction == LogicalDirection.Backward && textSegment.Start.CompareTo(textPosition) < 0 && textPosition.CompareTo(textSegment.End) <= 0)) { return true; } } return false; } // Returns the position of the next highlight start or end in an // indicated direction, or null if there is no such position. internal override StaticTextPointer GetNextChangePosition(StaticTextPointer textPosition, LogicalDirection direction) { StaticTextPointer transitionPosition; transitionPosition = StaticTextPointer.Null; if (!IsTextRangeEmpty(_selection) && !_selection.IsInterimSelection) { int segmentCount; List textSegments = _selection.TextSegments; TextSegment textSegment; segmentCount = textSegments.Count; if (direction == LogicalDirection.Forward) { for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) { textSegment = textSegments[segmentIndex]; // Ignore empty segments. // if (textSegment.Start.CompareTo(textSegment.End) != 0) { if (textPosition.CompareTo(textSegment.Start) < 0) { transitionPosition = textSegment.Start.CreateStaticPointer(); break; } else if (textPosition.CompareTo(textSegment.End) < 0) { transitionPosition = textSegment.End.CreateStaticPointer(); break; } } } } else { for (int segmentIndex = segmentCount - 1; segmentIndex >= 0; segmentIndex--) { textSegment = textSegments[segmentIndex]; if (textSegment.Start.CompareTo(textSegment.End) != 0) { if (textPosition.CompareTo(textSegment.End) > 0) { transitionPosition = textSegment.End.CreateStaticPointer(); break; } else if (textPosition.CompareTo(textSegment.Start) > 0) { transitionPosition = textSegment.Start.CreateStaticPointer(); break; } } } } } return transitionPosition; } // This is actual implementation to make highlight change notification. // This is called when highlight needs to be changed without public TextSelection change event. internal void InternalOnSelectionChanged() { ITextPointer newStart; ITextPointer newEnd; ITextPointer invalidRangeLeftStart; ITextPointer invalidRangeLeftEnd; ITextPointer invalidRangeRightStart; ITextPointer invalidRangeRightEnd; TextSelectionHighlightChangedEventArgs args; // If the current seleciton is interim selection, we do not highlight it // and we make newStart == newEnd. if (!_selection.IsInterimSelection) { newStart = _selection.Start; } else { newStart = _selection.End; } newEnd = _selection.End; // We want to raise an event that tracks the change tightly -- // only identifying content where the selection status actually changed. // This is important for render performance. // // Ex: // Old selection: 012 345 678 // New selection: 0123456 78 // // Should raise (3-3), (6-6) as deltas, not (3-6). // // Get the left side invalid range. if (_oldStart.CompareTo(newStart) < 0) { invalidRangeLeftStart = _oldStart; invalidRangeLeftEnd = TextPointerBase.Min(newStart, _oldEnd); } else { invalidRangeLeftStart = newStart; invalidRangeLeftEnd = TextPointerBase.Min(newEnd, _oldStart); } // Get the right side invalid range. if (_oldEnd.CompareTo(newEnd) < 0) { invalidRangeRightStart = TextPointerBase.Max(newStart, _oldEnd); invalidRangeRightEnd = newEnd; } else { invalidRangeRightStart = TextPointerBase.Max(newEnd, _oldStart); invalidRangeRightEnd = _oldEnd; } _oldStart = newStart; _oldEnd = newEnd; if (this.Changed != null) { if (invalidRangeLeftStart.CompareTo(invalidRangeLeftEnd) != 0 || invalidRangeRightStart.CompareTo(invalidRangeRightEnd) != 0) { args = new TextSelectionHighlightChangedEventArgs(invalidRangeLeftStart, invalidRangeLeftEnd, invalidRangeRightStart, invalidRangeRightEnd); this.Changed(this, args); } } } #endregion Internal Methods //------------------------------------------------------ // // Internal Properties // //------------------------------------------------------ #region Internal Properties ////// Type identifying this layer for Highlights.GetHighlightValue calls. /// internal override Type OwnerType { get { return typeof(TextSelection); } } #endregion Internal Properties //----------------------------------------------------- // // Internal Events // //------------------------------------------------------ #region Internal Events // Event raised when a highlight range is inserted, removed, moved, or // has a local property value change. internal override event HighlightChangedEventHandler Changed; #endregion Internal Events //----------------------------------------------------- // // Private Methods // //----------------------------------------------------- #region Private Methods // Callback for TextSelection.Moved event. // We use this event to trigger highlight change notifications. private void OnSelectionChanged(object sender, EventArgs e) { Invariant.Assert(_selection == (ITextSelection)sender); // text container and password text container are utilizing the new selection // that does not rely on text selection event. this is a performance optimization. object textContainer = _selection.Start.TextContainer; if ( textContainer is TextContainer || textContainer is System.Windows.Controls.PasswordTextContainer ) { return; } InternalOnSelectionChanged(); } // Check the text range whether it is empty or not without normalization. private bool IsTextRangeEmpty(ITextRange textRange) { // We assume that TextRange.TextSegments property getter does not normalize a range, // thus we can avoid re-entrancy. Invariant.Assert(textRange._TextSegments.Count > 0); return textRange._TextSegments[0].Start.CompareTo(textRange._TextSegments[textRange._TextSegments.Count - 1].End) == 0; } #endregion Private Methods //----------------------------------------------------- // // Private Types // //------------------------------------------------------ #region Private Types // Argument for the Changed event, encapsulates a highlight change. private class TextSelectionHighlightChangedEventArgs : HighlightChangedEventArgs { // Constructor. internal TextSelectionHighlightChangedEventArgs(ITextPointer invalidRangeLeftStart, ITextPointer invalidRangeLeftEnd, ITextPointer invalidRangeRightStart, ITextPointer invalidRangeRightEnd) { ListrangeArray; Invariant.Assert(invalidRangeLeftStart != invalidRangeLeftEnd || invalidRangeRightStart != invalidRangeRightEnd, "Unexpected empty range!"); if (invalidRangeLeftStart.CompareTo(invalidRangeLeftEnd) == 0) { rangeArray = new List (1); rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd)); } else if (invalidRangeRightStart.CompareTo(invalidRangeRightEnd) == 0) { rangeArray = new List (1); rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd)); } else { rangeArray = new List (2); rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd)); rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd)); } _ranges = new ReadOnlyCollection (rangeArray); } // Collection of changed content ranges. internal override IList Ranges { get { return _ranges; } } // Type identifying the owner of the changed layer. internal override Type OwnerType { get { return typeof(TextSelection); } } // Collection of changed content ranges. private readonly ReadOnlyCollection _ranges; } #endregion Private Types //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ #region Private Fields // TextSelection associated with this layer. private readonly ITextSelection _selection; // Previous position of the TextSelection, used to calculate deltas // on TextSelection.Moved events. private ITextPointer _oldStart; private ITextPointer _oldEnd; // Sentinel object used to tag highlights. private static readonly object _selectedValue; #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
- DSASignatureDeformatter.cs
- Ray3DHitTestResult.cs
- VisualState.cs
- MessageLogTraceRecord.cs
- SubtreeProcessor.cs
- StylusShape.cs
- EditorAttributeInfo.cs
- ISFClipboardData.cs
- DataGridViewAutoSizeModeEventArgs.cs
- CompiledXpathExpr.cs
- DataBindingList.cs
- SByteConverter.cs
- ClientOptions.cs
- RadioButton.cs
- MappingSource.cs
- StorageComplexTypeMapping.cs
- PhysicalOps.cs
- BitSet.cs
- DomainConstraint.cs
- DataGridViewRowCancelEventArgs.cs
- HitTestParameters3D.cs
- FontNamesConverter.cs
- Animatable.cs
- mactripleDES.cs
- SkinIDTypeConverter.cs
- SettingsProviderCollection.cs
- FixedTextPointer.cs
- ColumnCollection.cs
- GlyphManager.cs
- SoapEnvelopeProcessingElement.cs
- AsyncResult.cs
- PersonalizationStateInfo.cs
- SystemSounds.cs
- LinkLabel.cs
- SignatureToken.cs
- WMIInterop.cs
- CommonDialog.cs
- GACMembershipCondition.cs
- GeneratedCodeAttribute.cs
- InkCanvas.cs
- AffineTransform3D.cs
- ViewLoader.cs
- TypefaceMetricsCache.cs
- SplitterPanel.cs
- PathSegment.cs
- SoapFormatterSinks.cs
- InputReportEventArgs.cs
- Model3D.cs
- HttpListenerContext.cs
- Activator.cs
- MessageLoggingElement.cs
- RegexGroupCollection.cs
- Int64.cs
- SatelliteContractVersionAttribute.cs
- listitem.cs
- followingsibling.cs
- MultipleViewPatternIdentifiers.cs
- QilPatternFactory.cs
- ManifestResourceInfo.cs
- CategoryAttribute.cs
- Section.cs
- KeyTime.cs
- DefaultValidator.cs
- CalendarSelectionChangedEventArgs.cs
- DiscoveryMessageSequence11.cs
- ComponentEditorForm.cs
- WinCategoryAttribute.cs
- Stroke.cs
- SoapTypeAttribute.cs
- TableLayoutSettings.cs
- CommonProperties.cs
- URLMembershipCondition.cs
- GenericXmlSecurityTokenAuthenticator.cs
- BaseCollection.cs
- SqlXml.cs
- Soap.cs
- ItemCheckedEvent.cs
- ExpressionNormalizer.cs
- UpdateTracker.cs
- HitTestParameters.cs
- BinaryParser.cs
- ScriptingAuthenticationServiceSection.cs
- Parameter.cs
- TextBox.cs
- SymbolUsageManager.cs
- EntityProxyFactory.cs
- WaitingCursor.cs
- TypeHelpers.cs
- OrderingExpression.cs
- SQLDouble.cs
- GridViewAutomationPeer.cs
- TypefaceCollection.cs
- DataConnectionHelper.cs
- AbstractExpressions.cs
- AudienceUriMode.cs
- SemaphoreSlim.cs
- XAMLParseException.cs
- odbcmetadatafactory.cs
- ClosableStream.cs
- HtmlTableCellCollection.cs