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
- CompiledAction.cs
- SafeFileMapViewHandle.cs
- MouseEvent.cs
- ExtendedTransformFactory.cs
- ExceptionNotification.cs
- StaticDataManager.cs
- RawUIStateInputReport.cs
- HierarchicalDataBoundControlAdapter.cs
- CustomSignedXml.cs
- SpotLight.cs
- InvocationExpression.cs
- DataGridDesigner.cs
- ImageMap.cs
- BookmarkWorkItem.cs
- Walker.cs
- WebPartChrome.cs
- NetCodeGroup.cs
- SignatureHelper.cs
- ZoneIdentityPermission.cs
- DataGridViewTextBoxColumn.cs
- TriggerCollection.cs
- MouseActionConverter.cs
- LoginCancelEventArgs.cs
- SymDocumentType.cs
- AppDomainManager.cs
- OleDbWrapper.cs
- ObjectStateEntryDbUpdatableDataRecord.cs
- MemoryStream.cs
- LogExtent.cs
- SqlColumnizer.cs
- RecordBuilder.cs
- Oci.cs
- XamlSerializationHelper.cs
- DataTemplateSelector.cs
- SqlCacheDependencyDatabase.cs
- PrintingPermission.cs
- TextSpanModifier.cs
- RenderOptions.cs
- OrderPreservingMergeHelper.cs
- FileLoadException.cs
- ObjectNotFoundException.cs
- ResourceType.cs
- GlyphRunDrawing.cs
- Message.cs
- XslException.cs
- OleDbMetaDataFactory.cs
- MultipleCopiesCollection.cs
- GroupDescription.cs
- PocoEntityKeyStrategy.cs
- ArraySortHelper.cs
- XXXOnTypeBuilderInstantiation.cs
- XmlStreamNodeWriter.cs
- SecurityProtocol.cs
- BinaryReader.cs
- _FtpControlStream.cs
- FormDocumentDesigner.cs
- SafeLibraryHandle.cs
- FixedTextView.cs
- SystemColors.cs
- ByteKeyFrameCollection.cs
- SignalGate.cs
- DesignSurfaceCollection.cs
- MailAddressParser.cs
- TableStyle.cs
- TransformCryptoHandle.cs
- SerializerProvider.cs
- ZipIOExtraFieldElement.cs
- EventNotify.cs
- CanonicalFormWriter.cs
- TimeManager.cs
- TerminatorSinks.cs
- EditorResources.cs
- TypeLoadException.cs
- InfoCardClaimCollection.cs
- ValidationResults.cs
- CompareValidator.cs
- RequestQueue.cs
- ImagingCache.cs
- TextHintingModeValidation.cs
- TableProviderWrapper.cs
- x509utils.cs
- LOSFormatter.cs
- LinkedResourceCollection.cs
- WebConfigurationHost.cs
- InfoCardCryptoHelper.cs
- ToolBarButtonClickEvent.cs
- WinFormsSpinner.cs
- EmptyStringExpandableObjectConverter.cs
- DataTableMapping.cs
- Trace.cs
- arc.cs
- DirtyTextRange.cs
- ObjectListDesigner.cs
- SystemIPGlobalProperties.cs
- DocumentPage.cs
- XmlSerializerVersionAttribute.cs
- StrokeCollectionConverter.cs
- EventLogHandle.cs
- ProviderConnectionPoint.cs
- PermissionAttributes.cs