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
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AppDomainManager.cs
- DeobfuscatingStream.cs
- BrushMappingModeValidation.cs
- ListViewCancelEventArgs.cs
- BreakRecordTable.cs
- InputScopeConverter.cs
- SupportingTokenDuplexChannel.cs
- IIS7WorkerRequest.cs
- RSAOAEPKeyExchangeDeformatter.cs
- TimeZoneNotFoundException.cs
- ListInitExpression.cs
- Rijndael.cs
- HeaderUtility.cs
- FixedElement.cs
- Frame.cs
- ImageBrush.cs
- TextParagraph.cs
- DiscardableAttribute.cs
- XomlCompilerParameters.cs
- ToolStripItemGlyph.cs
- DigitShape.cs
- DrawingAttributeSerializer.cs
- DependencyObjectType.cs
- MissingMemberException.cs
- StatusBarItemAutomationPeer.cs
- KeyTime.cs
- ClientSession.cs
- KerberosSecurityTokenProvider.cs
- HuffmanTree.cs
- Connection.cs
- ToolStripButton.cs
- XmlSchemaGroup.cs
- DataGridViewColumnHeaderCell.cs
- AsnEncodedData.cs
- XmlSchemaObjectTable.cs
- PriorityQueue.cs
- ConfigXmlCDataSection.cs
- controlskin.cs
- TextPointer.cs
- CodeMethodInvokeExpression.cs
- LinearGradientBrush.cs
- IDictionary.cs
- DispatcherSynchronizationContext.cs
- ColumnResizeAdorner.cs
- WindowShowOrOpenTracker.cs
- BinaryNode.cs
- ListCommandEventArgs.cs
- ConsoleEntryPoint.cs
- ButtonBaseAdapter.cs
- TextRunTypographyProperties.cs
- BmpBitmapEncoder.cs
- LambdaExpression.cs
- PagerSettings.cs
- TextEndOfParagraph.cs
- SqlCacheDependencyDatabase.cs
- DelegatedStream.cs
- BatchStream.cs
- PathTooLongException.cs
- Accessible.cs
- HijriCalendar.cs
- PropertyTabAttribute.cs
- HandlerBase.cs
- SqlDependencyListener.cs
- ShadowGlyph.cs
- EventMap.cs
- DbProviderServices.cs
- Propagator.Evaluator.cs
- ScalarRestriction.cs
- BaseDataBoundControl.cs
- VersionValidator.cs
- Convert.cs
- Span.cs
- CorrelationValidator.cs
- DateTimeValueSerializerContext.cs
- SignedInfo.cs
- ObjectKeyFrameCollection.cs
- PeerPresenceInfo.cs
- DisplayMemberTemplateSelector.cs
- SqlBinder.cs
- Int32EqualityComparer.cs
- StackOverflowException.cs
- MaskDesignerDialog.cs
- DataRowExtensions.cs
- AutomationPropertyChangedEventArgs.cs
- CroppedBitmap.cs
- hresults.cs
- AdapterDictionary.cs
- FileUtil.cs
- MachineKeySection.cs
- WaitingCursor.cs
- AsyncContentLoadedEventArgs.cs
- ConfigsHelper.cs
- TextEditorContextMenu.cs
- CellIdBoolean.cs
- HttpCookiesSection.cs
- Rotation3D.cs
- SqlDataSourceRefreshSchemaForm.cs
- BevelBitmapEffect.cs
- ObjectStorage.cs
- Button.cs