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
- HitTestWithPointDrawingContextWalker.cs
- Material.cs
- SqlDataSourceFilteringEventArgs.cs
- DaylightTime.cs
- ProgramNode.cs
- Partitioner.cs
- UInt64Storage.cs
- AngleUtil.cs
- BuildProviderAppliesToAttribute.cs
- DragEvent.cs
- TagPrefixCollection.cs
- WhiteSpaceTrimStringConverter.cs
- TransportManager.cs
- BasicKeyConstraint.cs
- _LocalDataStore.cs
- Int64AnimationUsingKeyFrames.cs
- SvcFileManager.cs
- ExceptionAggregator.cs
- ConnectionManagementElement.cs
- OutputScopeManager.cs
- XMLSyntaxException.cs
- JapaneseCalendar.cs
- regiisutil.cs
- CounterSetInstance.cs
- MailAddress.cs
- ContextMenu.cs
- DataGridViewComboBoxEditingControl.cs
- ProxyElement.cs
- ModuleBuilder.cs
- safelinkcollection.cs
- ZipPackage.cs
- ManualWorkflowSchedulerService.cs
- MouseWheelEventArgs.cs
- ServiceModelConfigurationSection.cs
- ConnectionStringEditor.cs
- ContentPlaceHolderDesigner.cs
- TreeViewCancelEvent.cs
- ConstructorArgumentAttribute.cs
- KeyValuePairs.cs
- PenCursorManager.cs
- CaretElement.cs
- SemanticAnalyzer.cs
- CancellationTokenSource.cs
- ZipArchive.cs
- SectionUpdates.cs
- DurableDispatcherAddressingFault.cs
- CallbackCorrelationInitializer.cs
- XomlCompilerError.cs
- FilteredDataSetHelper.cs
- SslStream.cs
- AlgoModule.cs
- LogPolicy.cs
- RuntimeHelpers.cs
- Button.cs
- Operator.cs
- SchemaTypeEmitter.cs
- Enlistment.cs
- XmlLangPropertyAttribute.cs
- ManifestSignatureInformation.cs
- MenuItemStyleCollection.cs
- RowUpdatingEventArgs.cs
- Clock.cs
- SqlCommandSet.cs
- TypeProvider.cs
- XmlWellformedWriter.cs
- IntPtr.cs
- GlobalProxySelection.cs
- XsdBuildProvider.cs
- MonthCalendar.cs
- XmlAttributeCollection.cs
- TableLayoutCellPaintEventArgs.cs
- TypeDescriptionProvider.cs
- ProcessHost.cs
- BooleanSwitch.cs
- UserPreferenceChangedEventArgs.cs
- AnchoredBlock.cs
- ValidateNames.cs
- NavigationEventArgs.cs
- XamlFilter.cs
- FtpRequestCacheValidator.cs
- ConstantProjectedSlot.cs
- StyleSelector.cs
- OleDbStruct.cs
- GridItemCollection.cs
- ObjectDataSourceSelectingEventArgs.cs
- WebCodeGenerator.cs
- FtpWebRequest.cs
- Parameter.cs
- BypassElement.cs
- Misc.cs
- WindowsButton.cs
- InvalidWMPVersionException.cs
- BinaryExpression.cs
- MarkerProperties.cs
- ToolbarAUtomationPeer.cs
- ConnectionsZone.cs
- RequestResizeEvent.cs
- ThreadNeutralSemaphore.cs
- MobileSysDescriptionAttribute.cs
- Guid.cs