Code:
/ 4.0 / 4.0 / untmp / 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
- EditorZone.cs
- WindowsPen.cs
- SimpleWebHandlerParser.cs
- XmlDataSource.cs
- DataColumnChangeEvent.cs
- EnumerableCollectionView.cs
- VisemeEventArgs.cs
- XmlSchemaFacet.cs
- SecurityElement.cs
- ServiceOperation.cs
- DoubleLinkList.cs
- DelegatingHeader.cs
- AsyncParams.cs
- DbDataRecord.cs
- XmlValidatingReader.cs
- KeyedCollection.cs
- Registry.cs
- DiscoveryOperationContextExtension.cs
- TextViewBase.cs
- XmlIlGenerator.cs
- MachineKey.cs
- BooleanConverter.cs
- ServiceOperationDetailViewControl.cs
- VoiceChangeEventArgs.cs
- PasswordDeriveBytes.cs
- FlowLayoutPanel.cs
- EntryIndex.cs
- WebDisplayNameAttribute.cs
- URL.cs
- ServiceModelEnumValidator.cs
- IntegerValidator.cs
- FrameworkContentElement.cs
- ParameterBinding.cs
- altserialization.cs
- LocatorGroup.cs
- UserControlCodeDomTreeGenerator.cs
- TreeNode.cs
- PathFigure.cs
- IResourceProvider.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- ConstraintStruct.cs
- WebReferenceCollection.cs
- FileDialog_Vista.cs
- WinFormsSpinner.cs
- PlanCompiler.cs
- ConstantExpression.cs
- NullableConverter.cs
- PageSettings.cs
- CommonObjectSecurity.cs
- DbProviderServices.cs
- EventsTab.cs
- AnonymousIdentificationModule.cs
- DescendantBaseQuery.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- DateTimeOffsetConverter.cs
- odbcmetadatacollectionnames.cs
- ConditionalAttribute.cs
- ping.cs
- DragEventArgs.cs
- DataSetViewSchema.cs
- RepeaterItem.cs
- FlowDocumentPaginator.cs
- StickyNoteHelper.cs
- FlowPosition.cs
- ExpressionVisitor.cs
- SvcMapFileLoader.cs
- Base64Encoder.cs
- Material.cs
- ContentOperations.cs
- DnsPermission.cs
- ReachBasicContext.cs
- SafeSecurityHelper.cs
- TemplatePagerField.cs
- IPHostEntry.cs
- DecryptRequest.cs
- ProbeMatchesMessage11.cs
- DataFormats.cs
- HorizontalAlignConverter.cs
- ObjectKeyFrameCollection.cs
- MarshalByValueComponent.cs
- ObjectMaterializedEventArgs.cs
- CompoundFileStreamReference.cs
- AccessKeyManager.cs
- SchemaCollectionCompiler.cs
- cookie.cs
- SqlBinder.cs
- ConsoleCancelEventArgs.cs
- ViewStateModeByIdAttribute.cs
- RelationshipConverter.cs
- EntityChangedParams.cs
- CharUnicodeInfo.cs
- PropertyExpression.cs
- CustomAssemblyResolver.cs
- TraceUtility.cs
- SharedPerformanceCounter.cs
- EventlogProvider.cs
- DurableOperationAttribute.cs
- ItemCheckEvent.cs
- Array.cs
- OdbcPermission.cs