Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Documents / TextSelectionHighlightLayer.cs / 1305600 / TextSelectionHighlightLayer.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: Highlight rendering for the TextSelection. // // History: // 07/01/2004 : [....] - 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); 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 : [....] - 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); 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
- CellIdBoolean.cs
- CustomAttribute.cs
- ColumnMapTranslator.cs
- DataKeyCollection.cs
- StylusTip.cs
- DataServiceHostFactory.cs
- XslAstAnalyzer.cs
- FlagsAttribute.cs
- WmpBitmapDecoder.cs
- Camera.cs
- RowCache.cs
- XmlAttributeProperties.cs
- XmlNamespaceMappingCollection.cs
- XmlText.cs
- _FtpControlStream.cs
- JsonByteArrayDataContract.cs
- ExplicitDiscriminatorMap.cs
- PreviewPageInfo.cs
- DataRowComparer.cs
- DataSvcMapFile.cs
- SmtpNetworkElement.cs
- DragStartedEventArgs.cs
- TdsParserSafeHandles.cs
- ZipIOCentralDirectoryFileHeader.cs
- SizeAnimationBase.cs
- WebAdminConfigurationHelper.cs
- SqlClientWrapperSmiStreamChars.cs
- SelectionProcessor.cs
- ParseChildrenAsPropertiesAttribute.cs
- EntityContainerEmitter.cs
- ObjectConverter.cs
- SendingRequestEventArgs.cs
- IxmlLineInfo.cs
- Section.cs
- TrackingProfileSerializer.cs
- TextParagraph.cs
- DataRelationCollection.cs
- UriTemplateDispatchFormatter.cs
- Run.cs
- PrintingPermission.cs
- LogFlushAsyncResult.cs
- DesignTimeParseData.cs
- ParentUndoUnit.cs
- TemplateControl.cs
- Int32Storage.cs
- LZCodec.cs
- KnownTypesProvider.cs
- RelatedEnd.cs
- AxisAngleRotation3D.cs
- PointUtil.cs
- ServerProtocol.cs
- EnvelopedPkcs7.cs
- SqlConnectionPoolProviderInfo.cs
- SecurityHelper.cs
- TemplateNameScope.cs
- ListViewDesigner.cs
- AddInDeploymentState.cs
- SafeViewOfFileHandle.cs
- SortDescriptionCollection.cs
- VectorCollectionValueSerializer.cs
- CreateParams.cs
- CodeAttachEventStatement.cs
- SEHException.cs
- HttpSysSettings.cs
- DiagnosticTraceSource.cs
- URLEditor.cs
- AvTraceFormat.cs
- Border.cs
- FormViewInsertEventArgs.cs
- OperatorExpressions.cs
- QilFactory.cs
- EdmRelationshipRoleAttribute.cs
- NavigationProperty.cs
- EtwTrace.cs
- PolyBezierSegment.cs
- RootDesignerSerializerAttribute.cs
- XmlParserContext.cs
- XMLDiffLoader.cs
- RemotingException.cs
- Help.cs
- TextDecoration.cs
- querybuilder.cs
- XPathNodeIterator.cs
- CodeCommentStatementCollection.cs
- SqlDataReader.cs
- DateRangeEvent.cs
- RadioButtonBaseAdapter.cs
- WebReferenceCollection.cs
- XmlAttribute.cs
- TrustSection.cs
- DeclarativeCatalogPartDesigner.cs
- SqlProviderServices.cs
- PointLightBase.cs
- DesignTimeParseData.cs
- shaperfactory.cs
- ImageList.cs
- Mapping.cs
- MetafileHeader.cs
- SingleStorage.cs
- DataGridViewCellMouseEventArgs.cs