1 #pragma warning disable 1634, 1691 2 namespace System.Workflow.ComponentModel.Design 3 { 4 using System; 5 using System.IO; 6 using System.Drawing; 7 using System.CodeDom; 8 using System.Diagnostics; 9 using System.Collections; 10 using System.Collections.Generic; 11 using System.Windows.Forms; 12 using System.ComponentModel; 13 using System.Globalization; 14 using System.Drawing.Design; 15 using System.Drawing.Imaging; 16 using System.Drawing.Drawing2D; 17 using System.Windows.Forms.Design; 18 using System.ComponentModel.Design; 19 using System.Collections.Specialized; 20 using System.ComponentModel.Design.Serialization; 21 using System.Workflow.ComponentModel.Compiler; 22 using System.Workflow.ComponentModel.Serialization; 23 using System.Collections.ObjectModel; 24 using System.Reflection; 25 using System.Workflow.ComponentModel.Design; 26 using System.Runtime.Serialization.Formatters.Binary; 27 28 // 29 30 #region SequentialWorkflowRootDesigner Class 31 /// <summary> 32 /// Base class for root designer for workflow. It provides a consistent look and feel for all the roots. 33 /// The root designers associated with root activities have to be derived from SequentialWorkflowRootDesigner. 34 /// </summary> 35 [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")] 36 public class SequentialWorkflowRootDesigner : SequentialActivityDesigner 37 { 38 #region Statics 39 private const int HeaderFooterSizeIncr = 8; 40 private static readonly Image HeaderImage = DR.GetImage(DR.StartWorkflow); 41 private static readonly Image FooterImage = DR.GetImage(DR.EndWorkflow); 42 private static readonly Size PageStripItemSize = new Size(24, 20); 43 private static readonly Size MinSize = new Size(240, 240); 44 #endregion 45 46 #region Fields 47 //NOTE: The callingDesigner member is only set when the workflow is called from another 48 //workflow, this is used to hookup the parent chain. 49 private WorkflowHeader header; 50 private WorkflowFooter footer; 51 #endregion 52 53 #region Properties 54 55 #region Public Properties 56 public override string Text 57 { 58 get 59 { 60 return String.Empty; 61 } 62 } 63 64 public override Image Image 65 { 66 get 67 { 68 return Header.Image; //smart tag glyph needs an image 69 } 70 } 71 72 protected override Rectangle ImageRectangle 73 { 74 get 75 { 76 return Rectangle.Empty; //we are using image rect from the header for that... 77 } 78 } 79 80 public override bool CanExpandCollapse 81 { 82 get 83 { 84 return false; 85 } 86 } 87 88 public override Size MinimumSize 89 { 90 get 91 { 92 Size minimumSize = base.MinimumSize; 93 94 minimumSize.Width = Math.Max(minimumSize.Width, SequentialWorkflowRootDesigner.MinSize.Width); 95 minimumSize.Height = Math.Max(minimumSize.Width, SequentialWorkflowRootDesigner.MinSize.Height); 96 if (IsRootDesigner && InvokingDesigner == null) 97 { 98 minimumSize.Width = Math.Max(minimumSize.Width, ParentView.ViewPortSize.Width - 2 * WorkflowRootLayout.Separator.Width); 99 minimumSize.Height = Math.Max(minimumSize.Height, ParentView.ViewPortSize.Height - 2 * WorkflowRootLayout.Separator.Height); 100 } 101 102 return minimumSize; 103 } 104 } 105 #endregion 106 107 #region Protected Properties 108 /// <summary> 109 /// Gets the header associated with SequentialWorkflowRootDesigner 110 /// </summary> 111 protected virtual SequentialWorkflowHeaderFooter Header 112 { 113 get 114 { 115 if (this.header == null) 116 this.header = new WorkflowHeader(this); 117 return this.header; 118 } 119 } 120 121 /// <summary> 122 /// Gets the footer associated with SequentialWorkflowRootDesigner 123 /// </summary> 124 protected virtual SequentialWorkflowHeaderFooter Footer 125 { 126 get 127 { 128 if (this.footer == null) 129 this.footer = new WorkflowFooter(this); 130 return this.footer; 131 } 132 } 133 134 protected override int TitleHeight 135 { 136 get 137 { 138 int titleHeight = base.TitleHeight; 139 if (Header != null) 140 titleHeight += Header.Bounds.Height; 141 return titleHeight; 142 } 143 } 144 145 protected override bool ShowSmartTag 146 { 147 get 148 { 149 if (Header != null && !String.IsNullOrEmpty(Header.Text) && this.Views.Count > 1) 150 return true; 151 else 152 return base.ShowSmartTag; 153 } 154 } 155 156 protected override Rectangle SmartTagRectangle 157 { 158 get 159 { 160 Rectangle smartTagRectangle = Rectangle.Empty; 161 if (Header != null) 162 { 163 smartTagRectangle = Header.ImageRectangle; 164 } 165 166 return smartTagRectangle; 167 } 168 } 169 170 protected override CompositeActivityDesigner InvokingDesigner 171 { 172 get 173 { 174 return base.InvokingDesigner; 175 } 176 177 set 178 { 179 base.InvokingDesigner = value; 180 } 181 } 182 183 protected internal override ActivityDesignerGlyphCollection Glyphs 184 { 185 get 186 { 187 ActivityDesignerGlyphCollection glyphs = new ActivityDesignerGlyphCollection(base.Glyphs); 188 if (InvokingDesigner != null) 189 glyphs.Add(LockedActivityGlyph.Default); 190 return glyphs; 191 } 192 } 193 #endregion 194 195 #region Private Properties 196 internal override WorkflowLayout SupportedLayout 197 { 198 get 199 { 200 return new WorkflowRootLayout(Activity.Site); 201 } 202 } 203 204 private int OptimalHeight 205 { 206 get 207 { 208 CompositeDesignerTheme designerTheme = DesignerTheme as CompositeDesignerTheme; 209 if (designerTheme == null) 210 return 0; 211 212 //Calculate the size based on child size 213 int optimalHeight = 0; 214 215 if (ContainedDesigners.Count == 0) 216 { 217 optimalHeight += designerTheme.ConnectorSize.Height; //Add the height of first connector 218 optimalHeight += HelpTextSize.Height; 219 optimalHeight += designerTheme.ConnectorSize.Height; //Add the height of last connector 220 } 221 else 222 { 223 ActivityDesigner activeDesigner = ActiveDesigner; 224 if (activeDesigner == this) 225 optimalHeight += designerTheme.ConnectorSize.Height; 226 227 AmbientTheme ambientTheme = WorkflowTheme.CurrentTheme.AmbientTheme; 228 foreach (ActivityDesigner activityDesigner in ContainedDesigners) 229 { 230 Size childSize = activityDesigner.Size; 231 optimalHeight += childSize.Height; 232 233 if (activeDesigner == this) 234 optimalHeight += designerTheme.ConnectorSize.Height; 235 else 236 optimalHeight += 2 * ambientTheme.SelectionSize.Height; 237 } 238 } 239 240 return optimalHeight; 241 } 242 } 243 #endregion 244 245 #endregion 246 247 #region Methods 248 249 #region Public Methods CanBeParentedTo(CompositeActivityDesigner parentActivityDesigner)250 public override bool CanBeParentedTo(CompositeActivityDesigner parentActivityDesigner) 251 { 252 return false; 253 } 254 #endregion 255 256 #region Protected Methods GetInnerConnections(DesignerEdges edges)257 protected override ReadOnlyCollection<Point> GetInnerConnections(DesignerEdges edges) 258 { 259 List<Point> connectionPoints = new List<Point>(base.GetInnerConnections(edges)); 260 if (connectionPoints.Count > 0 && Footer != null && (edges & DesignerEdges.Bottom) > 0) 261 connectionPoints[connectionPoints.Count - 1] = new Point(connectionPoints[connectionPoints.Count - 1].X, connectionPoints[connectionPoints.Count - 1].Y - Footer.Bounds.Height); 262 return connectionPoints.AsReadOnly(); 263 } 264 OnSmartTagVisibilityChanged(bool visible)265 protected override void OnSmartTagVisibilityChanged(bool visible) 266 { 267 base.OnSmartTagVisibilityChanged(visible); 268 269 if (Header != null && !Header.TextRectangle.IsEmpty) 270 Invalidate(Header.TextRectangle); 271 } 272 OnLayoutSize(ActivityDesignerLayoutEventArgs e)273 protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs e) 274 { 275 Size size = base.OnLayoutSize(e); 276 277 //Make sure that we set the minimum size 278 WorkflowFooter footer = Footer as WorkflowFooter; 279 if (footer != null) 280 size.Height += footer.ImageRectangle.Height + 2 * e.AmbientTheme.Margin.Height + footer.FooterBarRectangle.Size.Height; 281 282 if (Header != null) 283 Header.OnLayout(e); 284 285 if (Footer != null) 286 Footer.OnLayout(e); 287 288 return size; 289 } 290 OnPaint(ActivityDesignerPaintEventArgs e)291 protected override void OnPaint(ActivityDesignerPaintEventArgs e) 292 { 293 base.OnPaint(e); 294 295 CompositeDesignerTheme compositeDesignerTheme = e.DesignerTheme as CompositeDesignerTheme; 296 if (compositeDesignerTheme == null) 297 return; 298 299 //Draw the watermark at right bottom 300 Rectangle watermarkRectangle = Rectangle.Empty; 301 if (compositeDesignerTheme.WatermarkImage != null) 302 { 303 Rectangle bounds = Bounds; 304 bounds.Inflate(-e.AmbientTheme.Margin.Width, -e.AmbientTheme.Margin.Height); 305 watermarkRectangle = ActivityDesignerPaint.GetRectangleFromAlignment(compositeDesignerTheme.WatermarkAlignment, bounds, compositeDesignerTheme.WatermarkImage.Size); 306 } 307 308 //Here we go, draw header and footer rectangles 309 if (Header != null) 310 Header.OnPaint(e); 311 312 if (Footer != null) 313 Footer.OnPaint(e); 314 } 315 #endregion 316 317 #region Internal Methods 318 //this is for the workflow header/footer class InternalPerformLayout()319 internal void InternalPerformLayout() 320 { 321 PerformLayout(); 322 } 323 #endregion 324 325 #endregion 326 327 #region Nested Classes 328 329 #region Class WorkflowHeader 330 private sealed class WorkflowHeader : SequentialWorkflowHeaderFooter 331 { WorkflowHeader(SequentialWorkflowRootDesigner parent)332 public WorkflowHeader(SequentialWorkflowRootDesigner parent) 333 : base(parent, true) 334 { 335 Image = SequentialWorkflowRootDesigner.HeaderImage; 336 } 337 338 public override Rectangle Bounds 339 { 340 get 341 { 342 Rectangle bounds = base.Bounds; 343 Rectangle textRectangle = base.TextRectangle; 344 if (MinHeaderBarHeight > textRectangle.Height) 345 bounds.Height += (MinHeaderBarHeight - textRectangle.Height); 346 return bounds; 347 } 348 } 349 350 public override Rectangle TextRectangle 351 { 352 get 353 { 354 Rectangle textRectangle = base.TextRectangle; 355 if (MinHeaderBarHeight > textRectangle.Height) 356 textRectangle.Y += (MinHeaderBarHeight - textRectangle.Height) / 2; 357 return textRectangle; 358 } 359 } 360 361 public override Rectangle ImageRectangle 362 { 363 get 364 { 365 Rectangle imageRectangle = base.ImageRectangle; 366 if (Image != null) 367 { 368 ActivityDesignerTheme designerTheme = AssociatedDesigner.DesignerTheme; 369 imageRectangle.X -= SequentialWorkflowRootDesigner.HeaderFooterSizeIncr / 2; 370 imageRectangle.Y = HeaderBarRectangle.Bottom + WorkflowTheme.CurrentTheme.AmbientTheme.Margin.Height; 371 imageRectangle.Width += SequentialWorkflowRootDesigner.HeaderFooterSizeIncr; 372 imageRectangle.Height += SequentialWorkflowRootDesigner.HeaderFooterSizeIncr; 373 } 374 return imageRectangle; 375 } 376 } 377 OnPaint(ActivityDesignerPaintEventArgs e)378 public override void OnPaint(ActivityDesignerPaintEventArgs e) 379 { 380 if (e == null) 381 throw new ArgumentNullException("e"); 382 383 Rectangle rectangle = HeaderBarRectangle; 384 Color color1 = Color.Empty; 385 Color color2 = Color.FromArgb(50, e.DesignerTheme.BorderColor); 386 using (Brush linearGradientBrush = new LinearGradientBrush(rectangle, color1, color2, LinearGradientMode.Vertical)) 387 { 388 e.Graphics.FillRectangle(linearGradientBrush, rectangle); 389 e.Graphics.DrawLine(e.DesignerTheme.BorderPen, rectangle.Left, rectangle.Bottom, rectangle.Right, rectangle.Bottom); 390 } 391 392 base.OnPaint(e); 393 } 394 395 private Rectangle HeaderBarRectangle 396 { 397 get 398 { 399 Rectangle headerBarRectangle = new Rectangle(); 400 headerBarRectangle.Location = AssociatedDesigner.Location; 401 headerBarRectangle.Width = AssociatedDesigner.Size.Width; 402 headerBarRectangle.Height = Math.Max(2 * WorkflowTheme.CurrentTheme.AmbientTheme.Margin.Height + base.textSize.Height, MinHeaderBarHeight); 403 return headerBarRectangle; 404 } 405 } 406 407 private int MinHeaderBarHeight 408 { 409 get 410 { 411 return 2 * WorkflowTheme.CurrentTheme.AmbientTheme.Margin.Height; 412 } 413 } 414 } 415 #endregion 416 417 #region Class WorkflowFooter 418 private sealed class WorkflowFooter : SequentialWorkflowHeaderFooter 419 { WorkflowFooter(SequentialWorkflowRootDesigner parent)420 public WorkflowFooter(SequentialWorkflowRootDesigner parent) 421 : base(parent, false) 422 { 423 Image = SequentialWorkflowRootDesigner.FooterImage; 424 } 425 426 public override Rectangle Bounds 427 { 428 get 429 { 430 Rectangle bounds = base.Bounds; 431 432 SequentialWorkflowRootDesigner rootDesigner = AssociatedDesigner as SequentialWorkflowRootDesigner; 433 bounds.Height = Math.Max(bounds.Height, rootDesigner.Size.Height - rootDesigner.TitleHeight - rootDesigner.OptimalHeight); 434 bounds.Y = rootDesigner.Location.Y + rootDesigner.TitleHeight + rootDesigner.OptimalHeight; 435 436 int minHeight = ImageRectangle.Height; 437 minHeight += (minHeight > 0) ? 2 * WorkflowTheme.CurrentTheme.AmbientTheme.Margin.Height : 0; 438 minHeight += MinFooterBarHeight; 439 440 bounds.Height = Math.Max(minHeight, bounds.Height); 441 return bounds; 442 } 443 } 444 445 public override Rectangle ImageRectangle 446 { 447 get 448 { 449 Rectangle imageRectangle = base.ImageRectangle; 450 if (Image != null) 451 { 452 SequentialWorkflowRootDesigner rootDesigner = AssociatedDesigner as SequentialWorkflowRootDesigner; 453 imageRectangle.X -= SequentialWorkflowRootDesigner.HeaderFooterSizeIncr / 2; 454 imageRectangle.Width += SequentialWorkflowRootDesigner.HeaderFooterSizeIncr; 455 imageRectangle.Height += SequentialWorkflowRootDesigner.HeaderFooterSizeIncr; 456 imageRectangle.Y = rootDesigner.Location.Y + rootDesigner.TitleHeight + rootDesigner.OptimalHeight; 457 imageRectangle.Y += WorkflowTheme.CurrentTheme.AmbientTheme.Margin.Height; 458 } 459 return imageRectangle; 460 } 461 } 462 OnPaint(ActivityDesignerPaintEventArgs e)463 public override void OnPaint(ActivityDesignerPaintEventArgs e) 464 { 465 if (e == null) 466 throw new ArgumentNullException("e"); 467 468 Rectangle rectangle = FooterBarRectangle; 469 if (!FooterBarRectangle.IsEmpty) 470 { 471 Color color1 = Color.Empty; 472 Color color2 = Color.FromArgb(50, e.DesignerTheme.BorderColor); 473 using (Brush linearGradientBrush = new LinearGradientBrush(rectangle, color2, color1, LinearGradientMode.Vertical)) 474 { 475 e.Graphics.FillRectangle(linearGradientBrush, rectangle); 476 e.Graphics.DrawLine(e.DesignerTheme.BorderPen, rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Top); 477 } 478 } 479 480 base.OnPaint(e); 481 } 482 483 internal Rectangle FooterBarRectangle 484 { 485 get 486 { 487 return Rectangle.Empty; 488 } 489 } 490 491 private int MinFooterBarHeight 492 { 493 get 494 { 495 return 0; 496 } 497 } 498 } 499 #endregion 500 501 #endregion 502 } 503 #endregion 504 505 } 506