GlyphManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Design / MessageFilters / GlyphManager.cs / 1305376 / GlyphManager.cs

                            namespace System.Workflow.ComponentModel.Design 
{
 	using System;
	using System.Drawing;
	using System.Collections; 
	using System.Collections.ObjectModel;
 	using System.Diagnostics; 
	using System.Windows.Forms; 
 	using System.ComponentModel;
 	using System.Drawing.Design; 
	using System.Drawing.Drawing2D;
 	using System.Collections.Generic;
	using System.ComponentModel.Design;
	using System.Workflow.ComponentModel.Design; 

    #region Class ActivityDesignerGlyphCollection 
    public sealed class ActivityDesignerGlyphCollection : List 
    {
        public ActivityDesignerGlyphCollection() 
        {
        }

        public ActivityDesignerGlyphCollection(IEnumerable glyphs) 
            : base(glyphs)
        { 
        } 

        public ActivityDesignerGlyphCollection(ActivityDesignerGlyphCollection glyphs) 
            : base(glyphs)
        {
        }
 
        internal DesignerGlyph this[Type type]
        { 
            get 
            {
                if (type == null) 
                    throw new ArgumentNullException();

                DesignerGlyph glyph = null;
                foreach (DesignerGlyph designerGlyph in this) 
                {
                    if (designerGlyph.GetType() == type) 
                    { 
                        glyph = designerGlyph;
                        break; 
                    }
                    else if (type.IsAssignableFrom(designerGlyph.GetType()) && glyph == null)
                    {
                        glyph = designerGlyph; 
                    }
                } 
 
                return glyph;
            } 
        }
    }
    #endregion
 
    #region Class DesignerGlyph
    public abstract class DesignerGlyph 
    { 
        public const int HighestPriority = 0;
        public const int NormalPriority = 10000; 
        public const int LowestPriority = 1000000;

        internal const int ConnectionPointPriority = 1;
        internal const int MoveAnchorPriority = 1; 
        internal const int ConfigErrorPriority = 2;
        internal const int ConnectorDragDropPriority = 2; 
        internal const int FadeGlyphPriority = 3; 
        internal const int LockedGlyphPriority = 3;
        internal const int ReadOnlyGlyphPriority = 3; 
        internal const int CommentPriority = 3;
        internal const int SelectionPriority = 4;
        internal const int NonExecutionStatePriority = 5;
 
        public virtual bool CanBeActivated
        { 
            get 
            {
                return false; 
            }
        }

        public virtual int Priority 
        {
            get 
            { 
                return DesignerGlyph.NormalPriority;
            } 
        }

        public virtual Rectangle GetBounds(ActivityDesigner designer, bool activated)
        { 
            if (designer == null)
                throw new ArgumentNullException("designer"); 
 
            return designer.Bounds;
        } 

        protected abstract void OnPaint(Graphics graphics, bool activated, AmbientTheme ambientTheme, ActivityDesigner designer);

        protected virtual void OnActivate(ActivityDesigner designer) 
        {
        } 
 
        internal void DrawActivated(Graphics graphics, ActivityDesigner designer)
        { 
            OnPaint(graphics, true, WorkflowTheme.CurrentTheme.AmbientTheme, designer);
        }

        internal void Draw(Graphics graphics, ActivityDesigner designer) 
        {
            OnPaint(graphics, false, WorkflowTheme.CurrentTheme.AmbientTheme, designer); 
        } 

        internal void Activate(ActivityDesigner designer) 
        {
            OnActivate(designer);
        }
 
        internal static int OnComparePriority(DesignerGlyph x, DesignerGlyph y)
        { 
            return (y.Priority - x.Priority); 
        }
    } 
    #endregion

	#region Class GlyphManager
 	internal class GlyphManager : WorkflowDesignerMessageFilter, IDesignerGlyphProviderService 
	{
 		#region Members and Constructor 
 		// cache all the services so that in the dispose we properly clean up ourselves 
        private List designerGlyphProviders = new List();
 
        // these two variables are only valid during MouseEnter and MouseLeave of a glyph
		private DesignerGlyph activeGlyph = null;
 		private ActivityDesigner activeDesigner = null;
 
		internal GlyphManager()
        { 
		} 

		protected override void Dispose(bool disposing) 
 		{
            this.designerGlyphProviders.Clear();
            this.activeGlyph = null;
            this.activeDesigner = null; 

			IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer; 
 			if (serviceContainer != null) 
 			{
				if (GetService(typeof(IDesignerGlyphProviderService)) != null) 
 					serviceContainer.RemoveService(typeof(IDesignerGlyphProviderService));
			}

            base.Dispose(disposing); 
        }
		#endregion 
 
		#region WorkflowDesignerMessageFilter Methods
 		protected override void Initialize(WorkflowView parentView) 
		{
 			base.Initialize(parentView);

 			IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer; 
			if (serviceContainer != null)
 			{ 
				if (GetService(typeof(IDesignerGlyphProviderService)) != null) 
					serviceContainer.RemoveService(typeof(IDesignerGlyphProviderService));
				serviceContainer.AddService(typeof(IDesignerGlyphProviderService), this); 
            }
 		}

		protected override bool OnMouseDown(MouseEventArgs eventArgs) 
 		{
            if (this.activeGlyph != null) 
            { 
 				this.activeGlyph.Activate(this.activeDesigner);
                return true; 
            }
            else
            {
                return false; 
            }
        } 
 
		//if there is an active glyph, handle the double click event as the single click event
 		//to make sure we dont execute the default action in that case 
		protected override bool OnMouseDoubleClick(MouseEventArgs eventArgs)
		{
			if (this.activeGlyph != null)
 			{ 
				this.activeGlyph.Activate(this.activeDesigner);
                return true; 
 			} 
 			return false;
		} 


 		protected override bool OnMouseMove(MouseEventArgs eventArgs)
		{ 
			RefreshActiveGlyph(ParentView.ClientPointToLogical(new Point(eventArgs.X, eventArgs.Y)));
			return false; 
 		} 

		protected override bool OnMouseEnter(MouseEventArgs eventArgs) 
 		{
 			RefreshActiveGlyph(ParentView.ClientPointToLogical(new Point(eventArgs.X, eventArgs.Y)));
			return false;
 		} 

		protected override bool OnMouseHover(MouseEventArgs eventArgs) 
		{ 
			RefreshActiveGlyph(ParentView.ClientPointToLogical(new Point(eventArgs.X, eventArgs.Y)));
 			return false; 
		}
        #endregion

 		#region IDesignerGlyphProviderService Implementation 
        void IDesignerGlyphProviderService.AddGlyphProvider(IDesignerGlyphProvider glyphProvider)
        { 
            if (!this.designerGlyphProviders.Contains(glyphProvider)) 
            {
                this.designerGlyphProviders.Add(glyphProvider); 
 				ParentView.InvalidateClientRectangle(Rectangle.Empty);
            }
        }
 
        void IDesignerGlyphProviderService.RemoveGlyphProvider(IDesignerGlyphProvider glyphProvider)
        { 
            this.designerGlyphProviders.Remove(glyphProvider); 
			ParentView.InvalidateClientRectangle(Rectangle.Empty);
        } 

        ReadOnlyCollection IDesignerGlyphProviderService.GlyphProviders
        {
            get 
            {
                return this.designerGlyphProviders.AsReadOnly(); 
            } 
        }
        #endregion 

 		#region Internal methods
        internal void DrawDesignerGlyphs(ActivityDesignerPaintEventArgs e, ActivityDesigner designer)
        { 
            foreach (DesignerGlyph glyph in GetDesignerGlyphs(designer))
                glyph.Draw(e.Graphics, designer); 
 
            if (this.activeGlyph != null && designer == this.activeDesigner)
                this.activeGlyph.DrawActivated(e.Graphics, this.activeDesigner); 
        }

        internal ActivityDesignerGlyphCollection GetDesignerGlyphs(ActivityDesigner designer)
        { 
            ActivityDesignerGlyphCollection glyphs = new ActivityDesignerGlyphCollection();
            if (designer.Glyphs != null) 
				glyphs.AddRange(designer.Glyphs); 

			foreach (IDesignerGlyphProvider glyphProvider in this.designerGlyphProviders) 
            {
                ActivityDesignerGlyphCollection extendedGlyphs = glyphProvider.GetGlyphs(designer);
                if (extendedGlyphs != null)
                    glyphs.AddRange(extendedGlyphs); 
            }
 
			glyphs.Sort(new Comparison(DesignerGlyph.OnComparePriority)); 
 			return glyphs;
        } 
		#endregion

 		#region Helper Methods
 		private void RefreshActiveGlyph(Point point) 
		{
 			WorkflowView parentView = ParentView; 
			if (parentView != null) 
            {
                DesignerGlyph previousActiveGlyph = this.activeGlyph; 

                if (this.activeGlyph == null || !this.activeGlyph.GetBounds(this.activeDesigner, true).Contains(point))
                {
                    ActivityDesigner newActiveDesigner = null; 
                    DesignerGlyph newActiveGlyph = GlyphFromPoint(point, out newActiveDesigner);
 
                    if (this.activeGlyph != null) 
                        parentView.InvalidateLogicalRectangle(this.activeGlyph.GetBounds(this.activeDesigner, true));
 
                    this.activeGlyph = newActiveGlyph;
                    this.activeDesigner = newActiveDesigner;

                    if (this.activeGlyph != null) 
                        parentView.InvalidateLogicalRectangle(this.activeGlyph.GetBounds(this.activeDesigner, true));
                } 
 
                if (previousActiveGlyph != this.activeGlyph)
                { 
					if (this.activeGlyph != null && this.activeGlyph.CanBeActivated)
						parentView.Cursor = Cursors.Hand;
                    else if (parentView.Cursor == Cursors.Hand)
 						parentView.Cursor = Cursors.Default; 
                }
            } 
        } 

        private class RectangleCollection 
        {
            private List rectangles = new List();

            internal void AddRectangle(Rectangle rectangle) 
            {
                this.rectangles.Add(rectangle); 
            } 

            internal bool IsPointInsideAnyRectangle(Point p) 
            {
                for (int i = 0; i < this.rectangles.Count; i++)
                {
                    if (this.rectangles[i].Contains(p)) 
                        return true;
                } 
                return false; 
            }
        } 

        private DesignerGlyph GlyphFromPoint(Point point, out ActivityDesigner activityDesigner)
		{
 			activityDesigner = null; 

 			WorkflowView parentView = ParentView; 
			if (parentView != null) 
 			{
                RectangleCollection collection = new RectangleCollection(); 
				{
					ActivityDesigner[] containedDesigners = GetActivityDesigners(parentView.ClientRectangleToLogical(new Rectangle(Point.Empty, parentView.ViewPortSize)));
					foreach (ActivityDesigner designer in containedDesigners)
 					{ 
                        if (!collection.IsPointInsideAnyRectangle(point))
						{ 
 							foreach (DesignerGlyph glyph in GetDesignerGlyphs(designer)) 
 							{
								if (glyph.GetBounds(designer, false).Contains(point)) 
 								{
									if (glyph.CanBeActivated)
									{
										activityDesigner = designer; 
 										return glyph;
									} 
 								} 
 							}
						} 
                        collection.AddRectangle(designer.Bounds);
 					}
				}
			} 

			return null; 
 		} 

		//Please note that before changing this algorithm, you need to know that changing this algorithm 
 		//will affect the z order of the designers and will affect the way glyphs are drawn.
 		//Here what we are using depth first search algorithm to maintain the Z order.
		//Please note that even though one might think the algo might cause some inefficiency, the algo
 		//has been timed for huge workflow and typically takes < 20ms to execute 
		private ActivityDesigner[] GetActivityDesigners(Rectangle logicalViewPort)
		{ 
			//We need to go to the deepest point and then start drawing outwards 
 			List designerList = new List();
			bool viewPortEmpty = logicalViewPort.IsEmpty; 

            ActivityDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(ParentView);
 			if (rootDesigner != null)
 			{ 
				Stack designerStack = new Stack();
 
 				designerStack.Push(rootDesigner); 
                CompositeActivityDesigner compositeDesigner = rootDesigner as CompositeActivityDesigner;
				if (compositeDesigner != null && compositeDesigner.ContainedDesigners.Count > 0) 
                    designerStack.Push(compositeDesigner.ContainedDesigners);

                while (designerStack.Count > 0)
				{ 
					object topOfStack = designerStack.Pop();
 					ICollection designers = topOfStack as ICollection; 
					if (designers != null) 
 					{
 						foreach (ActivityDesigner activityDesigner in designers) 
						{
 							if ((viewPortEmpty || logicalViewPort.IntersectsWith(activityDesigner.Bounds)) && activityDesigner.IsVisible)
							{
								designerStack.Push(activityDesigner); 
								compositeDesigner = activityDesigner as CompositeActivityDesigner;
 								if (compositeDesigner != null && compositeDesigner.ContainedDesigners.Count > 0) 
									designerStack.Push(compositeDesigner.ContainedDesigners); 
 							}
 						} 
					}
 					else
					{
						//Draw glyphs for composite designers 
						designerList.Add((ActivityDesigner)topOfStack);
 					} 
				} 
 			}
 
 			return designerList.ToArray();
		}
 		#endregion
	} 
	#endregion
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
´╗┐namespace System.Workflow.ComponentModel.Design 
{
 	using System;
	using System.Drawing;
	using System.Collections; 
	using System.Collections.ObjectModel;
 	using System.Diagnostics; 
	using System.Windows.Forms; 
 	using System.ComponentModel;
 	using System.Drawing.Design; 
	using System.Drawing.Drawing2D;
 	using System.Collections.Generic;
	using System.ComponentModel.Design;
	using System.Workflow.ComponentModel.Design; 

    #region Class ActivityDesignerGlyphCollection 
    public sealed class ActivityDesignerGlyphCollection : List 
    {
        public ActivityDesignerGlyphCollection() 
        {
        }

        public ActivityDesignerGlyphCollection(IEnumerable glyphs) 
            : base(glyphs)
        { 
        } 

        public ActivityDesignerGlyphCollection(ActivityDesignerGlyphCollection glyphs) 
            : base(glyphs)
        {
        }
 
        internal DesignerGlyph this[Type type]
        { 
            get 
            {
                if (type == null) 
                    throw new ArgumentNullException();

                DesignerGlyph glyph = null;
                foreach (DesignerGlyph designerGlyph in this) 
                {
                    if (designerGlyph.GetType() == type) 
                    { 
                        glyph = designerGlyph;
                        break; 
                    }
                    else if (type.IsAssignableFrom(designerGlyph.GetType()) && glyph == null)
                    {
                        glyph = designerGlyph; 
                    }
                } 
 
                return glyph;
            } 
        }
    }
    #endregion
 
    #region Class DesignerGlyph
    public abstract class DesignerGlyph 
    { 
        public const int HighestPriority = 0;
        public const int NormalPriority = 10000; 
        public const int LowestPriority = 1000000;

        internal const int ConnectionPointPriority = 1;
        internal const int MoveAnchorPriority = 1; 
        internal const int ConfigErrorPriority = 2;
        internal const int ConnectorDragDropPriority = 2; 
        internal const int FadeGlyphPriority = 3; 
        internal const int LockedGlyphPriority = 3;
        internal const int ReadOnlyGlyphPriority = 3; 
        internal const int CommentPriority = 3;
        internal const int SelectionPriority = 4;
        internal const int NonExecutionStatePriority = 5;
 
        public virtual bool CanBeActivated
        { 
            get 
            {
                return false; 
            }
        }

        public virtual int Priority 
        {
            get 
            { 
                return DesignerGlyph.NormalPriority;
            } 
        }

        public virtual Rectangle GetBounds(ActivityDesigner designer, bool activated)
        { 
            if (designer == null)
                throw new ArgumentNullException("designer"); 
 
            return designer.Bounds;
        } 

        protected abstract void OnPaint(Graphics graphics, bool activated, AmbientTheme ambientTheme, ActivityDesigner designer);

        protected virtual void OnActivate(ActivityDesigner designer) 
        {
        } 
 
        internal void DrawActivated(Graphics graphics, ActivityDesigner designer)
        { 
            OnPaint(graphics, true, WorkflowTheme.CurrentTheme.AmbientTheme, designer);
        }

        internal void Draw(Graphics graphics, ActivityDesigner designer) 
        {
            OnPaint(graphics, false, WorkflowTheme.CurrentTheme.AmbientTheme, designer); 
        } 

        internal void Activate(ActivityDesigner designer) 
        {
            OnActivate(designer);
        }
 
        internal static int OnComparePriority(DesignerGlyph x, DesignerGlyph y)
        { 
            return (y.Priority - x.Priority); 
        }
    } 
    #endregion

	#region Class GlyphManager
 	internal class GlyphManager : WorkflowDesignerMessageFilter, IDesignerGlyphProviderService 
	{
 		#region Members and Constructor 
 		// cache all the services so that in the dispose we properly clean up ourselves 
        private List designerGlyphProviders = new List();
 
        // these two variables are only valid during MouseEnter and MouseLeave of a glyph
		private DesignerGlyph activeGlyph = null;
 		private ActivityDesigner activeDesigner = null;
 
		internal GlyphManager()
        { 
		} 

		protected override void Dispose(bool disposing) 
 		{
            this.designerGlyphProviders.Clear();
            this.activeGlyph = null;
            this.activeDesigner = null; 

			IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer; 
 			if (serviceContainer != null) 
 			{
				if (GetService(typeof(IDesignerGlyphProviderService)) != null) 
 					serviceContainer.RemoveService(typeof(IDesignerGlyphProviderService));
			}

            base.Dispose(disposing); 
        }
		#endregion 
 
		#region WorkflowDesignerMessageFilter Methods
 		protected override void Initialize(WorkflowView parentView) 
		{
 			base.Initialize(parentView);

 			IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer; 
			if (serviceContainer != null)
 			{ 
				if (GetService(typeof(IDesignerGlyphProviderService)) != null) 
					serviceContainer.RemoveService(typeof(IDesignerGlyphProviderService));
				serviceContainer.AddService(typeof(IDesignerGlyphProviderService), this); 
            }
 		}

		protected override bool OnMouseDown(MouseEventArgs eventArgs) 
 		{
            if (this.activeGlyph != null) 
            { 
 				this.activeGlyph.Activate(this.activeDesigner);
                return true; 
            }
            else
            {
                return false; 
            }
        } 
 
		//if there is an active glyph, handle the double click event as the single click event
 		//to make sure we dont execute the default action in that case 
		protected override bool OnMouseDoubleClick(MouseEventArgs eventArgs)
		{
			if (this.activeGlyph != null)
 			{ 
				this.activeGlyph.Activate(this.activeDesigner);
                return true; 
 			} 
 			return false;
		} 


 		protected override bool OnMouseMove(MouseEventArgs eventArgs)
		{ 
			RefreshActiveGlyph(ParentView.ClientPointToLogical(new Point(eventArgs.X, eventArgs.Y)));
			return false; 
 		} 

		protected override bool OnMouseEnter(MouseEventArgs eventArgs) 
 		{
 			RefreshActiveGlyph(ParentView.ClientPointToLogical(new Point(eventArgs.X, eventArgs.Y)));
			return false;
 		} 

		protected override bool OnMouseHover(MouseEventArgs eventArgs) 
		{ 
			RefreshActiveGlyph(ParentView.ClientPointToLogical(new Point(eventArgs.X, eventArgs.Y)));
 			return false; 
		}
        #endregion

 		#region IDesignerGlyphProviderService Implementation 
        void IDesignerGlyphProviderService.AddGlyphProvider(IDesignerGlyphProvider glyphProvider)
        { 
            if (!this.designerGlyphProviders.Contains(glyphProvider)) 
            {
                this.designerGlyphProviders.Add(glyphProvider); 
 				ParentView.InvalidateClientRectangle(Rectangle.Empty);
            }
        }
 
        void IDesignerGlyphProviderService.RemoveGlyphProvider(IDesignerGlyphProvider glyphProvider)
        { 
            this.designerGlyphProviders.Remove(glyphProvider); 
			ParentView.InvalidateClientRectangle(Rectangle.Empty);
        } 

        ReadOnlyCollection IDesignerGlyphProviderService.GlyphProviders
        {
            get 
            {
                return this.designerGlyphProviders.AsReadOnly(); 
            } 
        }
        #endregion 

 		#region Internal methods
        internal void DrawDesignerGlyphs(ActivityDesignerPaintEventArgs e, ActivityDesigner designer)
        { 
            foreach (DesignerGlyph glyph in GetDesignerGlyphs(designer))
                glyph.Draw(e.Graphics, designer); 
 
            if (this.activeGlyph != null && designer == this.activeDesigner)
                this.activeGlyph.DrawActivated(e.Graphics, this.activeDesigner); 
        }

        internal ActivityDesignerGlyphCollection GetDesignerGlyphs(ActivityDesigner designer)
        { 
            ActivityDesignerGlyphCollection glyphs = new ActivityDesignerGlyphCollection();
            if (designer.Glyphs != null) 
				glyphs.AddRange(designer.Glyphs); 

			foreach (IDesignerGlyphProvider glyphProvider in this.designerGlyphProviders) 
            {
                ActivityDesignerGlyphCollection extendedGlyphs = glyphProvider.GetGlyphs(designer);
                if (extendedGlyphs != null)
                    glyphs.AddRange(extendedGlyphs); 
            }
 
			glyphs.Sort(new Comparison(DesignerGlyph.OnComparePriority)); 
 			return glyphs;
        } 
		#endregion

 		#region Helper Methods
 		private void RefreshActiveGlyph(Point point) 
		{
 			WorkflowView parentView = ParentView; 
			if (parentView != null) 
            {
                DesignerGlyph previousActiveGlyph = this.activeGlyph; 

                if (this.activeGlyph == null || !this.activeGlyph.GetBounds(this.activeDesigner, true).Contains(point))
                {
                    ActivityDesigner newActiveDesigner = null; 
                    DesignerGlyph newActiveGlyph = GlyphFromPoint(point, out newActiveDesigner);
 
                    if (this.activeGlyph != null) 
                        parentView.InvalidateLogicalRectangle(this.activeGlyph.GetBounds(this.activeDesigner, true));
 
                    this.activeGlyph = newActiveGlyph;
                    this.activeDesigner = newActiveDesigner;

                    if (this.activeGlyph != null) 
                        parentView.InvalidateLogicalRectangle(this.activeGlyph.GetBounds(this.activeDesigner, true));
                } 
 
                if (previousActiveGlyph != this.activeGlyph)
                { 
					if (this.activeGlyph != null && this.activeGlyph.CanBeActivated)
						parentView.Cursor = Cursors.Hand;
                    else if (parentView.Cursor == Cursors.Hand)
 						parentView.Cursor = Cursors.Default; 
                }
            } 
        } 

        private class RectangleCollection 
        {
            private List rectangles = new List();

            internal void AddRectangle(Rectangle rectangle) 
            {
                this.rectangles.Add(rectangle); 
            } 

            internal bool IsPointInsideAnyRectangle(Point p) 
            {
                for (int i = 0; i < this.rectangles.Count; i++)
                {
                    if (this.rectangles[i].Contains(p)) 
                        return true;
                } 
                return false; 
            }
        } 

        private DesignerGlyph GlyphFromPoint(Point point, out ActivityDesigner activityDesigner)
		{
 			activityDesigner = null; 

 			WorkflowView parentView = ParentView; 
			if (parentView != null) 
 			{
                RectangleCollection collection = new RectangleCollection(); 
				{
					ActivityDesigner[] containedDesigners = GetActivityDesigners(parentView.ClientRectangleToLogical(new Rectangle(Point.Empty, parentView.ViewPortSize)));
					foreach (ActivityDesigner designer in containedDesigners)
 					{ 
                        if (!collection.IsPointInsideAnyRectangle(point))
						{ 
 							foreach (DesignerGlyph glyph in GetDesignerGlyphs(designer)) 
 							{
								if (glyph.GetBounds(designer, false).Contains(point)) 
 								{
									if (glyph.CanBeActivated)
									{
										activityDesigner = designer; 
 										return glyph;
									} 
 								} 
 							}
						} 
                        collection.AddRectangle(designer.Bounds);
 					}
				}
			} 

			return null; 
 		} 

		//Please note that before changing this algorithm, you need to know that changing this algorithm 
 		//will affect the z order of the designers and will affect the way glyphs are drawn.
 		//Here what we are using depth first search algorithm to maintain the Z order.
		//Please note that even though one might think the algo might cause some inefficiency, the algo
 		//has been timed for huge workflow and typically takes < 20ms to execute 
		private ActivityDesigner[] GetActivityDesigners(Rectangle logicalViewPort)
		{ 
			//We need to go to the deepest point and then start drawing outwards 
 			List designerList = new List();
			bool viewPortEmpty = logicalViewPort.IsEmpty; 

            ActivityDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(ParentView);
 			if (rootDesigner != null)
 			{ 
				Stack designerStack = new Stack();
 
 				designerStack.Push(rootDesigner); 
                CompositeActivityDesigner compositeDesigner = rootDesigner as CompositeActivityDesigner;
				if (compositeDesigner != null && compositeDesigner.ContainedDesigners.Count > 0) 
                    designerStack.Push(compositeDesigner.ContainedDesigners);

                while (designerStack.Count > 0)
				{ 
					object topOfStack = designerStack.Pop();
 					ICollection designers = topOfStack as ICollection; 
					if (designers != null) 
 					{
 						foreach (ActivityDesigner activityDesigner in designers) 
						{
 							if ((viewPortEmpty || logicalViewPort.IntersectsWith(activityDesigner.Bounds)) && activityDesigner.IsVisible)
							{
								designerStack.Push(activityDesigner); 
								compositeDesigner = activityDesigner as CompositeActivityDesigner;
 								if (compositeDesigner != null && compositeDesigner.ContainedDesigners.Count > 0) 
									designerStack.Push(compositeDesigner.ContainedDesigners); 
 							}
 						} 
					}
 					else
					{
						//Draw glyphs for composite designers 
						designerList.Add((ActivityDesigner)topOfStack);
 					} 
				} 
 			}
 
 			return designerList.ToArray();
		}
 		#endregion
	} 
	#endregion
} 

// 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