HighlightComponent.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / Annotations / Component / HighlightComponent.cs / 1 / HighlightComponent.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: AnnotationComponent that visualizes highlights 
// 
// History:
//  01/31/2005 ssimova - Created 
//
//---------------------------------------------------------------------------

using System; 
using MS.Internal;
using System.Diagnostics; 
using System.Collections; 
using System.Collections.Generic;
using System.Windows; 
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;
using MS.Internal.Text; 
using System.Xml;
using System.IO; 
using System.Windows.Annotations; 
using System.Reflection;
using System.Windows.Annotations.Storage; 
using System.Windows.Controls;
using MS.Internal.Annotations.Anchoring;
using MS.Utility;
 

namespace MS.Internal.Annotations.Component 
{ 
    // Highlight rendering for the Annotation highlight and sticky note anchor.
    // TBD 
    internal class HighlightComponent : Canvas, IAnnotationComponent, IHighlightRange
    {
        #region Constructor
 
        /// 
        /// Creates a new instance of the HighlightComponent 
        ///  
        public HighlightComponent()
        { 
        }

        /// 
        /// Creates a new instance of the HighlightComponent with 
        /// nondefault priority and type;
        ///  
        /// component priority 
        /// if true - highlight only content of tables, figures and floaters
        /// component type 
        public HighlightComponent(int priority, bool highlightContent, XmlQualifiedName type)
            : base()
        {
            if (type == null) 
            {
                throw new ArgumentNullException("type"); 
            } 
            _priority = priority;
            _type = type; 
            _highlightContent = highlightContent;
        }

        #endregion Constructor 

        #region Public Properties 
 
        /// 
        /// Return a copy of the list of IAttachedAnnotations held by this component 
        /// 
        public IList AttachedAnnotations
        {
            get 
            {
                ArrayList list = new ArrayList(); 
                if (_attachedAnnotation != null) 
                {
                    list.Add(_attachedAnnotation); 
                }
                return list;
            }
 
        }
 
        ///  
        /// Sets and gets the context this annotation component is hosted in.
        ///  
        /// Context this annotation component is hosted in
        public PresentationContext PresentationContext
        {
            get 
            {
                return _presentationContext; 
            } 

            set 
            {
                _presentationContext = value;
            }
        } 

        ///  
        /// Sets and gets the Z-order of this component. NOP - 
        /// Highlight does not have Z-order
        ///  
        /// Context this annotation component is hosted in
        public int ZOrder
        {
            get 
            {
                return -1; 
            } 

            set 
            {
            }
        }
 
        /// 
        /// The annotation type name 
        ///  
        public static XmlQualifiedName TypeName
        { 
            get
            {
                return _name;
            } 
        }
 
        ///  
        /// gets and sets the default backgroud color for the highlight
        ///  
        public Color DefaultBackground
        {
            get
            { 
                return _defaultBackroundColor;
            } 
            set 
            {
                _defaultBackroundColor = value; 
            }

        }
 
        /// 
        /// gets and sets the default foregroud color for the highlight 
        ///  
        public Color DefaultActiveBackground
        { 
            get
            {
                return _defaultActiveBackgroundColor;
            } 
            set
            { 
                _defaultActiveBackgroundColor = value; 
            }
 
        }

        /// 
        /// Highlight color 
        /// 
        public Brush HighlightBrush 
        { 
            set
            { 
                SetValue(HighlightComponent.HighlightBrushProperty, value);
            }
        }
 
        //those properies are exposed to allow external components like StickyNote to synchronize their color
        // with Highlight colors 
        public static DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrushProperty", typeof(Brush), typeof(HighlightComponent)); 

        ///  
        /// Returns the one element the annotation component is attached to.
        /// 
        /// 
        public UIElement AnnotatedElement 
        {
            get 
            { 
                return _attachedAnnotation != null ? (_attachedAnnotation.Parent as UIElement) : null;
            } 
        }

        /// 
        /// When the value is set to true - the AnnotatedElement content has changed - 
        /// save the value and invalidate the visual, so we can recalculate the geometry.
        /// The value is set to false when the geometry is synced with the content 
        ///  
        public bool IsDirty
        { 
            get
            {
                return _isDirty;
            } 

            set 
            { 
                _isDirty = value;
                if (value) 
                    InvalidateChildren();
            }
        }
 
        #endregion Public Properties
 
        #region Public Methods 

        ///  
        /// The HighlightComponent uses built-in highlight rendering, so no transformation is needed
        /// 
        /// Transform to the AnnotatedElement.
        /// Transform to the annotation component 
        public GeneralTransform GetDesiredTransform(GeneralTransform transform)
        { 
            return transform; 
        }
 
        /// 
        /// Add an attached annotation to the component. The attached anchor will be used to add
        /// a highlight to the appropriate TextContainer
        ///  
        /// The attached annotation to be added to the component
        public void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation) 
        { 
            if (_attachedAnnotation != null)
            { 
                throw new ArgumentException(SR.Get(SRID.MoreThanOneAttachedAnnotation));
            }

            //fire trace event 
            EventTrace.NormalTraceEvent(EventTraceGuidId.ADDATTACHEDHIGHLIGHTGUID, EventType.StartEvent);
 
            //check input data and retrieve the TextContainer 
            ITextContainer textContainer = CheckInputData(attachedAnnotation);
 
            TextAnchor textAnchor = attachedAnnotation.AttachedAnchor as TextAnchor;

            //Get highlight Colors from the cargo. For undefined Colors the default values are used
            GetColors(attachedAnnotation.Annotation, out _background, out _selectedBackground); 
            _range = textAnchor;
 
            Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null"); 

            //get or create AnnotationHighlightLayer in the textContainer 
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer;
            if (highlightLayer == null)
            {
                highlightLayer = new AnnotationHighlightLayer(); 
                textContainer.Highlights.AddLayer(highlightLayer);
            } 
 
            //save the attached annotation
            _attachedAnnotation = attachedAnnotation; 

            //register for cargo changes
            _attachedAnnotation.Annotation.CargoChanged += new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);
 
            //add this highlight range
            highlightLayer.AddRange(this); 
            HighlightBrush = new SolidColorBrush(_background); 
            IsHitTestVisible = false;
 
            //fire trace event
            EventTrace.NormalTraceEvent(EventTraceGuidId.ADDATTACHEDHIGHLIGHTGUID, EventType.EndEvent);

        } 

        ///  
        /// Remove an attached annotation from the component 
        /// 
        /// The attached annotation to be removed from the component 
        public void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            if (attachedAnnotation == null)
            { 
                throw new ArgumentNullException("attachedAnnotation");
            } 
 
            if (attachedAnnotation != _attachedAnnotation)
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidAttachedAnnotation), "attachedAnnotation");
            }

            Invariant.Assert(_range != null, "null highlight range"); 

            //fire trace event 
            EventTrace.NormalTraceEvent(EventTraceGuidId.REMOVEATTACHEDHIGHLIGHTGUID, EventType.StartEvent); 

            //check input data and retrieve the TextContainer 
            ITextContainer textContainer = CheckInputData(attachedAnnotation);

            Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null");
 
            //get AnnotationHighlightLayer in the textContainer
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer; 
            Invariant.Assert(highlightLayer != null, "AnnotationHighlightLayer is not initialized"); 

            //unregister of cargo changes 
            _attachedAnnotation.Annotation.CargoChanged -= new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);

            highlightLayer.RemoveRange(this);
 
            //highlight is removed - remove the attached annotation and the data
            _attachedAnnotation = null; 
 
            //fire trace event
            EventTrace.NormalTraceEvent(EventTraceGuidId.REMOVEATTACHEDHIGHLIGHTGUID, EventType.EndEvent); 


        }
 
        /// 
        /// Modify an attached annotation that is held by the component 
        ///  
        /// The attached annotation after modification
        /// The attached anchor previously associated with the attached annotation. 
        /// The previous attachment level of the attached annotation.
        public void ModifyAttachedAnnotation(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel)
        {
            throw new NotSupportedException(SR.Get(SRID.NotSupported)); 
        }
 
        ///  
        /// Sets highlight color to active/inactive
        /// true - activate, false = deactivate 
        /// 
        public void Activate(bool active)
        {
            //return if the state is unchanged 
            if (_active == active)
                return; 
 
            //get the highlight layer
            if (_attachedAnnotation == null) 
            {
                throw new InvalidOperationException(SR.Get(SRID.NoAttachedAnnotationToModify));
            }
 
            TextAnchor textAnchor = _attachedAnnotation.AttachedAnchor as TextAnchor;
            Invariant.Assert(textAnchor != null, "AttachedAnchor is not a text anchor"); 
 
            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer; 
            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");

            //get AnnotationHighlightLayer in the textContainer
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer; 
            Invariant.Assert(highlightLayer != null, "AnnotationHighlightLayer is not initialized");
 
            highlightLayer.ActivateRange(this, active); 
            _active = active;
 
            if (active)
                HighlightBrush = new SolidColorBrush(_selectedBackground);
            else
                HighlightBrush = new SolidColorBrush(_background); 
        }
 
        #endregion Public Methods 

        //----------------------------------------------------- 
        //
        //  IHighlightRange implementation
        //
        //----------------------------------------------------- 
        #region IHighlightRange implementation
 
        #region Internal Methods 

        ///  
        /// Adds a new shape to the children of the corresponding visual
        /// 
        /// the new child
        void IHighlightRange.AddChild(Shape child) 
        {
            Children.Add(child); 
        } 

 
        /// 
        /// Removes a shape from the children of the corresponding visual
        /// 
        /// the new child 
        void IHighlightRange.RemoveChild(Shape child)
        { 
            Children.Remove(child); 
        }
 
        #endregion Internal Methods
        //------------------------------------------------------
        //
        //  Internal properties 
        //
        //----------------------------------------------------- 
 
        #region Internal Properties
 
        /// 
        /// Highlight Background color
        /// 
        Color IHighlightRange.Background 
        {
            get 
            { 
                return _background;
            } 
        }

        /// 
        /// Highlight color if highlight is active 
        /// 
        Color IHighlightRange.SelectedBackground 
        { 
            get
            { 
                return _selectedBackground;
            }
        }
 
        /// 
        /// Highlight TextSegment 
        ///  
        TextAnchor IHighlightRange.Range
        { 
            get
            {
                return _range;
            } 
        }
 
        ///  
        /// Highlight priority
        ///  
        int IHighlightRange.Priority
        {
            get
            { 
                return _priority;
            } 
        } 

        ///  
        /// if true - highlight only the content of tables, figures and floaters
        /// 
        bool IHighlightRange.HighlightContent
        { 
            get
            { 
                return _highlightContent; 
            }
        } 

        #endregion Internal Properties

        #endregion IHighlightRange implementation 

 
        #region Internal Methods 
        internal bool IsSelected(ITextRange selection)
        { 
            if (selection == null)
            {
                throw new ArgumentNullException("selection");
            } 
            Invariant.Assert(_attachedAnnotation != null, "No _attachedAnnotation");
 
            // For activation based on the selection state, we need to use anchors that 
            // span virtualized content (i.e., content that isn't visible).  For that we
            // grab the 'fullly resolved' anchors instead of the anchors used by the 
            // framework for all other purposes.
            TextAnchor fullAnchor = _attachedAnnotation.FullyAttachedAnchor as TextAnchor;
            //Debug.Assert(fullAnchor != null, "null TextAnchor");
            if (fullAnchor == null) 
                return false;
 
            return fullAnchor.IsOverlapping(selection.TextSegments); 
        }
 
        /// 
        /// Looks for Colors from the Annotation's cargo. If corresponding Color is present
        /// set it to the input parameter. Otherwise leave the parameter intact.
        ///  
        /// The Annotation
        /// background Color 
        /// background Color for active highlight 
        internal static void GetCargoColors(Annotation annot, ref Nullable backgroundColor, ref Nullable activeBackgroundColor)
        { 
            Invariant.Assert(annot != null, "annotation is null");

            ICollection cargos = annot.Cargos;
 
            if (cargos != null)
            { 
                foreach (AnnotationResource cargo in cargos) 
                {
                    if (cargo.Name == HighlightResourceName) 
                    {
                        ICollection contents = cargo.Contents;
                        foreach (XmlElement content in contents)
                        { 
                            if ((content.LocalName == ColorsContentName) &&
                                (content.NamespaceURI == AnnotationXmlConstants.Namespaces.BaseSchemaNamespace)) 
                            { 

                                if (content.Attributes[BackgroundAttributeName] != null) 
                                    backgroundColor = GetColor(content.Attributes[BackgroundAttributeName].Value);
                                if (content.Attributes[ActiveBackgroundAttributeName] != null)
                                    activeBackgroundColor = GetColor(content.Attributes[ActiveBackgroundAttributeName].Value);
                            } 
                        }
 
                    } 
                }
            } 
        }

        #endregion Internal Methods
 
        #region Private Methods
 
        ///  
        /// Checks if this attachedAnnotation data - AttachedAnchor and Annotation
        ///  
        /// The AttachedAnnotation
        /// The AttachedAnchor TextContainer
        private ITextContainer CheckInputData(IAttachedAnnotation attachedAnnotation)
        { 

            if (attachedAnnotation == null) 
            { 
                throw new ArgumentNullException("attachedAnnotation");
            } 

            TextAnchor textAnchor = attachedAnnotation.AttachedAnchor as TextAnchor;
            if (textAnchor == null)
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidAttachedAnchor), "attachedAnnotation");
            } 
 
            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer; 

            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");

            if (attachedAnnotation.Annotation == null) 
            {
                throw new ArgumentException(SR.Get(SRID.AnnotationIsNull), "attachedAnnotation"); 
            } 

            //check annotation type 
            if (!_type.Equals(attachedAnnotation.Annotation.AnnotationType))
            {
                throw new ArgumentException(SR.Get(SRID.NotHighlightAnnotationType, attachedAnnotation.Annotation.AnnotationType.ToString()), "attachedAnnotation");
            } 

            return textContainer; 
 
        }
 
        /// 
        /// Converts a string to Color object
        /// 
        /// Color string 
        /// Color object
        private static Color GetColor(string color) 
        { 
            return (Color)ColorConverter.ConvertFromString(color);
        } 

        /// 
        /// Gets the Colors from the Annotation's cargo. If corresponding Color is not present
        /// a default value is used. 
        /// 
        /// The Annotation 
        /// background Color 
        /// background Color for active highlight
        private void GetColors(Annotation annot, out Color backgroundColor, out Color activeBackgroundColor) 
        {
            Nullable tempBackgroundColor = _defaultBackroundColor;
            Nullable tempActiveBackgroundColor = _defaultActiveBackgroundColor;
            GetCargoColors(annot, ref tempBackgroundColor, ref tempActiveBackgroundColor); 
            backgroundColor = (Color)tempBackgroundColor;
            activeBackgroundColor = (Color)tempActiveBackgroundColor; 
        } 

        ///  
        /// Called when the Annotation cargo changes
        /// 
        /// the sender
        /// event arguments 
        private void OnAnnotationUpdated(object sender, AnnotationResourceChangedEventArgs args)
        { 
            Invariant.Assert(_attachedAnnotation != null && _attachedAnnotation.Annotation == args.Annotation, "_attachedAnnotation is different than the input one"); 
            Invariant.Assert(_range != null, "The highlight range is null");
 
            //get text container
            TextAnchor textAnchor = _attachedAnnotation.AttachedAnchor as TextAnchor;
            Invariant.Assert(textAnchor != null, "wrong anchor type of the saved attached annotation");
 
            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer; 
 
            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");
 

            //Get highlight Colors from the cargo and update the highlight layer
            Color background, activeBackground;
            GetColors(args.Annotation, out background, out activeBackground); 

            if (!_background.Equals(background) || 
                !_selectedBackground.Equals(activeBackground)) 
            {
                //modify the highlight 
                Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null");

                //get AnnotationHighlightLayer in the textContainer
                AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer; 
                if (highlightLayer == null)
                { 
                    throw new InvalidDataException(SR.Get(SRID.MissingAnnotationHighlightLayer)); 
                }
 
                //change the colors and invalidate
                _background = background;
                _selectedBackground = activeBackground;
                highlightLayer.ModifiedRange(this); 
            }
 
        } 

        ///  
        /// Invalidating the measure on all the children (which are Shapes)
        /// causes them to recalculate their desired geometry
        /// 
        private void InvalidateChildren() 
        {
            // Invalidating the measure on all the children (which are Shapes) 
            // causes them to recalculate their desired geometry 
            foreach (Visual child in Children)
            { 
                Shape uiChild = child as Shape;
                Invariant.Assert(uiChild != null, "HighlightComponent has non-Shape children.");
                uiChild.InvalidateMeasure();
            } 

            //reset the Dirty flag 
            IsDirty = false; 

        } 

        #endregion Private Methods

        #region Public Fields 

        //resource and content names 
        public const string HighlightResourceName = "Highlight"; 
        public const string ColorsContentName = "Colors";
        public const string BackgroundAttributeName = "Background"; 
        public const string ActiveBackgroundAttributeName = "ActiveBackground";


        #endregion Public Fields 

        //------------------------------------------------------ 
        // 
        //  Private fields
        // 
        //------------------------------------------------------

        #region Private Fields
 
        private Color _background;
        private Color _selectedBackground; 
        private TextAnchor _range; //the entire range for this highlight 

        private IAttachedAnnotation _attachedAnnotation; 
        private PresentationContext _presentationContext;
        private static readonly XmlQualifiedName _name = new XmlQualifiedName("Highlight", AnnotationXmlConstants.Namespaces.BaseSchemaNamespace);
        private XmlQualifiedName _type = _name;
        private int _priority = 0;  //used for highlights Z-order. The segment owners are ordered with highest 
        // priority first
        private bool _highlightContent = true; //highlight only the content of tables, figures and floaters 
        private bool _active = false; //saves the highlight state - active or not 
        private bool _isDirty = true; //shows if the annotation is in [....] with the content of the AnnotatedElement
 
        //default color colors
        private Color _defaultBackroundColor = (Color)ColorConverter.ConvertFromString("#33FFFF00");
        private Color _defaultActiveBackgroundColor = (Color)ColorConverter.ConvertFromString("#339ACD32");
 
        #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: AnnotationComponent that visualizes highlights 
// 
// History:
//  01/31/2005 ssimova - Created 
//
//---------------------------------------------------------------------------

using System; 
using MS.Internal;
using System.Diagnostics; 
using System.Collections; 
using System.Collections.Generic;
using System.Windows; 
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;
using MS.Internal.Text; 
using System.Xml;
using System.IO; 
using System.Windows.Annotations; 
using System.Reflection;
using System.Windows.Annotations.Storage; 
using System.Windows.Controls;
using MS.Internal.Annotations.Anchoring;
using MS.Utility;
 

namespace MS.Internal.Annotations.Component 
{ 
    // Highlight rendering for the Annotation highlight and sticky note anchor.
    // TBD 
    internal class HighlightComponent : Canvas, IAnnotationComponent, IHighlightRange
    {
        #region Constructor
 
        /// 
        /// Creates a new instance of the HighlightComponent 
        ///  
        public HighlightComponent()
        { 
        }

        /// 
        /// Creates a new instance of the HighlightComponent with 
        /// nondefault priority and type;
        ///  
        /// component priority 
        /// if true - highlight only content of tables, figures and floaters
        /// component type 
        public HighlightComponent(int priority, bool highlightContent, XmlQualifiedName type)
            : base()
        {
            if (type == null) 
            {
                throw new ArgumentNullException("type"); 
            } 
            _priority = priority;
            _type = type; 
            _highlightContent = highlightContent;
        }

        #endregion Constructor 

        #region Public Properties 
 
        /// 
        /// Return a copy of the list of IAttachedAnnotations held by this component 
        /// 
        public IList AttachedAnnotations
        {
            get 
            {
                ArrayList list = new ArrayList(); 
                if (_attachedAnnotation != null) 
                {
                    list.Add(_attachedAnnotation); 
                }
                return list;
            }
 
        }
 
        ///  
        /// Sets and gets the context this annotation component is hosted in.
        ///  
        /// Context this annotation component is hosted in
        public PresentationContext PresentationContext
        {
            get 
            {
                return _presentationContext; 
            } 

            set 
            {
                _presentationContext = value;
            }
        } 

        ///  
        /// Sets and gets the Z-order of this component. NOP - 
        /// Highlight does not have Z-order
        ///  
        /// Context this annotation component is hosted in
        public int ZOrder
        {
            get 
            {
                return -1; 
            } 

            set 
            {
            }
        }
 
        /// 
        /// The annotation type name 
        ///  
        public static XmlQualifiedName TypeName
        { 
            get
            {
                return _name;
            } 
        }
 
        ///  
        /// gets and sets the default backgroud color for the highlight
        ///  
        public Color DefaultBackground
        {
            get
            { 
                return _defaultBackroundColor;
            } 
            set 
            {
                _defaultBackroundColor = value; 
            }

        }
 
        /// 
        /// gets and sets the default foregroud color for the highlight 
        ///  
        public Color DefaultActiveBackground
        { 
            get
            {
                return _defaultActiveBackgroundColor;
            } 
            set
            { 
                _defaultActiveBackgroundColor = value; 
            }
 
        }

        /// 
        /// Highlight color 
        /// 
        public Brush HighlightBrush 
        { 
            set
            { 
                SetValue(HighlightComponent.HighlightBrushProperty, value);
            }
        }
 
        //those properies are exposed to allow external components like StickyNote to synchronize their color
        // with Highlight colors 
        public static DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrushProperty", typeof(Brush), typeof(HighlightComponent)); 

        ///  
        /// Returns the one element the annotation component is attached to.
        /// 
        /// 
        public UIElement AnnotatedElement 
        {
            get 
            { 
                return _attachedAnnotation != null ? (_attachedAnnotation.Parent as UIElement) : null;
            } 
        }

        /// 
        /// When the value is set to true - the AnnotatedElement content has changed - 
        /// save the value and invalidate the visual, so we can recalculate the geometry.
        /// The value is set to false when the geometry is synced with the content 
        ///  
        public bool IsDirty
        { 
            get
            {
                return _isDirty;
            } 

            set 
            { 
                _isDirty = value;
                if (value) 
                    InvalidateChildren();
            }
        }
 
        #endregion Public Properties
 
        #region Public Methods 

        ///  
        /// The HighlightComponent uses built-in highlight rendering, so no transformation is needed
        /// 
        /// Transform to the AnnotatedElement.
        /// Transform to the annotation component 
        public GeneralTransform GetDesiredTransform(GeneralTransform transform)
        { 
            return transform; 
        }
 
        /// 
        /// Add an attached annotation to the component. The attached anchor will be used to add
        /// a highlight to the appropriate TextContainer
        ///  
        /// The attached annotation to be added to the component
        public void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation) 
        { 
            if (_attachedAnnotation != null)
            { 
                throw new ArgumentException(SR.Get(SRID.MoreThanOneAttachedAnnotation));
            }

            //fire trace event 
            EventTrace.NormalTraceEvent(EventTraceGuidId.ADDATTACHEDHIGHLIGHTGUID, EventType.StartEvent);
 
            //check input data and retrieve the TextContainer 
            ITextContainer textContainer = CheckInputData(attachedAnnotation);
 
            TextAnchor textAnchor = attachedAnnotation.AttachedAnchor as TextAnchor;

            //Get highlight Colors from the cargo. For undefined Colors the default values are used
            GetColors(attachedAnnotation.Annotation, out _background, out _selectedBackground); 
            _range = textAnchor;
 
            Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null"); 

            //get or create AnnotationHighlightLayer in the textContainer 
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer;
            if (highlightLayer == null)
            {
                highlightLayer = new AnnotationHighlightLayer(); 
                textContainer.Highlights.AddLayer(highlightLayer);
            } 
 
            //save the attached annotation
            _attachedAnnotation = attachedAnnotation; 

            //register for cargo changes
            _attachedAnnotation.Annotation.CargoChanged += new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);
 
            //add this highlight range
            highlightLayer.AddRange(this); 
            HighlightBrush = new SolidColorBrush(_background); 
            IsHitTestVisible = false;
 
            //fire trace event
            EventTrace.NormalTraceEvent(EventTraceGuidId.ADDATTACHEDHIGHLIGHTGUID, EventType.EndEvent);

        } 

        ///  
        /// Remove an attached annotation from the component 
        /// 
        /// The attached annotation to be removed from the component 
        public void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
        {
            if (attachedAnnotation == null)
            { 
                throw new ArgumentNullException("attachedAnnotation");
            } 
 
            if (attachedAnnotation != _attachedAnnotation)
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidAttachedAnnotation), "attachedAnnotation");
            }

            Invariant.Assert(_range != null, "null highlight range"); 

            //fire trace event 
            EventTrace.NormalTraceEvent(EventTraceGuidId.REMOVEATTACHEDHIGHLIGHTGUID, EventType.StartEvent); 

            //check input data and retrieve the TextContainer 
            ITextContainer textContainer = CheckInputData(attachedAnnotation);

            Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null");
 
            //get AnnotationHighlightLayer in the textContainer
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer; 
            Invariant.Assert(highlightLayer != null, "AnnotationHighlightLayer is not initialized"); 

            //unregister of cargo changes 
            _attachedAnnotation.Annotation.CargoChanged -= new AnnotationResourceChangedEventHandler(OnAnnotationUpdated);

            highlightLayer.RemoveRange(this);
 
            //highlight is removed - remove the attached annotation and the data
            _attachedAnnotation = null; 
 
            //fire trace event
            EventTrace.NormalTraceEvent(EventTraceGuidId.REMOVEATTACHEDHIGHLIGHTGUID, EventType.EndEvent); 


        }
 
        /// 
        /// Modify an attached annotation that is held by the component 
        ///  
        /// The attached annotation after modification
        /// The attached anchor previously associated with the attached annotation. 
        /// The previous attachment level of the attached annotation.
        public void ModifyAttachedAnnotation(IAttachedAnnotation attachedAnnotation, object previousAttachedAnchor, AttachmentLevel previousAttachmentLevel)
        {
            throw new NotSupportedException(SR.Get(SRID.NotSupported)); 
        }
 
        ///  
        /// Sets highlight color to active/inactive
        /// true - activate, false = deactivate 
        /// 
        public void Activate(bool active)
        {
            //return if the state is unchanged 
            if (_active == active)
                return; 
 
            //get the highlight layer
            if (_attachedAnnotation == null) 
            {
                throw new InvalidOperationException(SR.Get(SRID.NoAttachedAnnotationToModify));
            }
 
            TextAnchor textAnchor = _attachedAnnotation.AttachedAnchor as TextAnchor;
            Invariant.Assert(textAnchor != null, "AttachedAnchor is not a text anchor"); 
 
            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer; 
            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");

            //get AnnotationHighlightLayer in the textContainer
            AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer; 
            Invariant.Assert(highlightLayer != null, "AnnotationHighlightLayer is not initialized");
 
            highlightLayer.ActivateRange(this, active); 
            _active = active;
 
            if (active)
                HighlightBrush = new SolidColorBrush(_selectedBackground);
            else
                HighlightBrush = new SolidColorBrush(_background); 
        }
 
        #endregion Public Methods 

        //----------------------------------------------------- 
        //
        //  IHighlightRange implementation
        //
        //----------------------------------------------------- 
        #region IHighlightRange implementation
 
        #region Internal Methods 

        ///  
        /// Adds a new shape to the children of the corresponding visual
        /// 
        /// the new child
        void IHighlightRange.AddChild(Shape child) 
        {
            Children.Add(child); 
        } 

 
        /// 
        /// Removes a shape from the children of the corresponding visual
        /// 
        /// the new child 
        void IHighlightRange.RemoveChild(Shape child)
        { 
            Children.Remove(child); 
        }
 
        #endregion Internal Methods
        //------------------------------------------------------
        //
        //  Internal properties 
        //
        //----------------------------------------------------- 
 
        #region Internal Properties
 
        /// 
        /// Highlight Background color
        /// 
        Color IHighlightRange.Background 
        {
            get 
            { 
                return _background;
            } 
        }

        /// 
        /// Highlight color if highlight is active 
        /// 
        Color IHighlightRange.SelectedBackground 
        { 
            get
            { 
                return _selectedBackground;
            }
        }
 
        /// 
        /// Highlight TextSegment 
        ///  
        TextAnchor IHighlightRange.Range
        { 
            get
            {
                return _range;
            } 
        }
 
        ///  
        /// Highlight priority
        ///  
        int IHighlightRange.Priority
        {
            get
            { 
                return _priority;
            } 
        } 

        ///  
        /// if true - highlight only the content of tables, figures and floaters
        /// 
        bool IHighlightRange.HighlightContent
        { 
            get
            { 
                return _highlightContent; 
            }
        } 

        #endregion Internal Properties

        #endregion IHighlightRange implementation 

 
        #region Internal Methods 
        internal bool IsSelected(ITextRange selection)
        { 
            if (selection == null)
            {
                throw new ArgumentNullException("selection");
            } 
            Invariant.Assert(_attachedAnnotation != null, "No _attachedAnnotation");
 
            // For activation based on the selection state, we need to use anchors that 
            // span virtualized content (i.e., content that isn't visible).  For that we
            // grab the 'fullly resolved' anchors instead of the anchors used by the 
            // framework for all other purposes.
            TextAnchor fullAnchor = _attachedAnnotation.FullyAttachedAnchor as TextAnchor;
            //Debug.Assert(fullAnchor != null, "null TextAnchor");
            if (fullAnchor == null) 
                return false;
 
            return fullAnchor.IsOverlapping(selection.TextSegments); 
        }
 
        /// 
        /// Looks for Colors from the Annotation's cargo. If corresponding Color is present
        /// set it to the input parameter. Otherwise leave the parameter intact.
        ///  
        /// The Annotation
        /// background Color 
        /// background Color for active highlight 
        internal static void GetCargoColors(Annotation annot, ref Nullable backgroundColor, ref Nullable activeBackgroundColor)
        { 
            Invariant.Assert(annot != null, "annotation is null");

            ICollection cargos = annot.Cargos;
 
            if (cargos != null)
            { 
                foreach (AnnotationResource cargo in cargos) 
                {
                    if (cargo.Name == HighlightResourceName) 
                    {
                        ICollection contents = cargo.Contents;
                        foreach (XmlElement content in contents)
                        { 
                            if ((content.LocalName == ColorsContentName) &&
                                (content.NamespaceURI == AnnotationXmlConstants.Namespaces.BaseSchemaNamespace)) 
                            { 

                                if (content.Attributes[BackgroundAttributeName] != null) 
                                    backgroundColor = GetColor(content.Attributes[BackgroundAttributeName].Value);
                                if (content.Attributes[ActiveBackgroundAttributeName] != null)
                                    activeBackgroundColor = GetColor(content.Attributes[ActiveBackgroundAttributeName].Value);
                            } 
                        }
 
                    } 
                }
            } 
        }

        #endregion Internal Methods
 
        #region Private Methods
 
        ///  
        /// Checks if this attachedAnnotation data - AttachedAnchor and Annotation
        ///  
        /// The AttachedAnnotation
        /// The AttachedAnchor TextContainer
        private ITextContainer CheckInputData(IAttachedAnnotation attachedAnnotation)
        { 

            if (attachedAnnotation == null) 
            { 
                throw new ArgumentNullException("attachedAnnotation");
            } 

            TextAnchor textAnchor = attachedAnnotation.AttachedAnchor as TextAnchor;
            if (textAnchor == null)
            { 
                throw new ArgumentException(SR.Get(SRID.InvalidAttachedAnchor), "attachedAnnotation");
            } 
 
            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer; 

            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");

            if (attachedAnnotation.Annotation == null) 
            {
                throw new ArgumentException(SR.Get(SRID.AnnotationIsNull), "attachedAnnotation"); 
            } 

            //check annotation type 
            if (!_type.Equals(attachedAnnotation.Annotation.AnnotationType))
            {
                throw new ArgumentException(SR.Get(SRID.NotHighlightAnnotationType, attachedAnnotation.Annotation.AnnotationType.ToString()), "attachedAnnotation");
            } 

            return textContainer; 
 
        }
 
        /// 
        /// Converts a string to Color object
        /// 
        /// Color string 
        /// Color object
        private static Color GetColor(string color) 
        { 
            return (Color)ColorConverter.ConvertFromString(color);
        } 

        /// 
        /// Gets the Colors from the Annotation's cargo. If corresponding Color is not present
        /// a default value is used. 
        /// 
        /// The Annotation 
        /// background Color 
        /// background Color for active highlight
        private void GetColors(Annotation annot, out Color backgroundColor, out Color activeBackgroundColor) 
        {
            Nullable tempBackgroundColor = _defaultBackroundColor;
            Nullable tempActiveBackgroundColor = _defaultActiveBackgroundColor;
            GetCargoColors(annot, ref tempBackgroundColor, ref tempActiveBackgroundColor); 
            backgroundColor = (Color)tempBackgroundColor;
            activeBackgroundColor = (Color)tempActiveBackgroundColor; 
        } 

        ///  
        /// Called when the Annotation cargo changes
        /// 
        /// the sender
        /// event arguments 
        private void OnAnnotationUpdated(object sender, AnnotationResourceChangedEventArgs args)
        { 
            Invariant.Assert(_attachedAnnotation != null && _attachedAnnotation.Annotation == args.Annotation, "_attachedAnnotation is different than the input one"); 
            Invariant.Assert(_range != null, "The highlight range is null");
 
            //get text container
            TextAnchor textAnchor = _attachedAnnotation.AttachedAnchor as TextAnchor;
            Invariant.Assert(textAnchor != null, "wrong anchor type of the saved attached annotation");
 
            //this should be in a fixed or flow textcontainer
            ITextContainer textContainer = textAnchor.Start.TextContainer; 
 
            Invariant.Assert(textContainer != null, "TextAnchor does not belong to a TextContainer");
 

            //Get highlight Colors from the cargo and update the highlight layer
            Color background, activeBackground;
            GetColors(args.Annotation, out background, out activeBackground); 

            if (!_background.Equals(background) || 
                !_selectedBackground.Equals(activeBackground)) 
            {
                //modify the highlight 
                Invariant.Assert(textContainer.Highlights != null, "textContainer.Highlights is null");

                //get AnnotationHighlightLayer in the textContainer
                AnnotationHighlightLayer highlightLayer = textContainer.Highlights.GetLayer(typeof(HighlightComponent)) as AnnotationHighlightLayer; 
                if (highlightLayer == null)
                { 
                    throw new InvalidDataException(SR.Get(SRID.MissingAnnotationHighlightLayer)); 
                }
 
                //change the colors and invalidate
                _background = background;
                _selectedBackground = activeBackground;
                highlightLayer.ModifiedRange(this); 
            }
 
        } 

        ///  
        /// Invalidating the measure on all the children (which are Shapes)
        /// causes them to recalculate their desired geometry
        /// 
        private void InvalidateChildren() 
        {
            // Invalidating the measure on all the children (which are Shapes) 
            // causes them to recalculate their desired geometry 
            foreach (Visual child in Children)
            { 
                Shape uiChild = child as Shape;
                Invariant.Assert(uiChild != null, "HighlightComponent has non-Shape children.");
                uiChild.InvalidateMeasure();
            } 

            //reset the Dirty flag 
            IsDirty = false; 

        } 

        #endregion Private Methods

        #region Public Fields 

        //resource and content names 
        public const string HighlightResourceName = "Highlight"; 
        public const string ColorsContentName = "Colors";
        public const string BackgroundAttributeName = "Background"; 
        public const string ActiveBackgroundAttributeName = "ActiveBackground";


        #endregion Public Fields 

        //------------------------------------------------------ 
        // 
        //  Private fields
        // 
        //------------------------------------------------------

        #region Private Fields
 
        private Color _background;
        private Color _selectedBackground; 
        private TextAnchor _range; //the entire range for this highlight 

        private IAttachedAnnotation _attachedAnnotation; 
        private PresentationContext _presentationContext;
        private static readonly XmlQualifiedName _name = new XmlQualifiedName("Highlight", AnnotationXmlConstants.Namespaces.BaseSchemaNamespace);
        private XmlQualifiedName _type = _name;
        private int _priority = 0;  //used for highlights Z-order. The segment owners are ordered with highest 
        // priority first
        private bool _highlightContent = true; //highlight only the content of tables, figures and floaters 
        private bool _active = false; //saves the highlight state - active or not 
        private bool _isDirty = true; //shows if the annotation is in [....] with the content of the AnnotatedElement
 
        //default color colors
        private Color _defaultBackroundColor = (Color)ColorConverter.ConvertFromString("#33FFFF00");
        private Color _defaultActiveBackgroundColor = (Color)ColorConverter.ConvertFromString("#339ACD32");
 
        #endregion Private Fields
 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK