1 namespace System.Workflow.Activities
2 {
3     using System;
4     using System.Text;
5     using System.Reflection;
6     using System.Collections;
7     using System.Collections.Generic;
8     using System.Collections.ObjectModel;
9     using System.CodeDom;
10     using System.ComponentModel;
11     using System.ComponentModel.Design;
12     using System.Drawing.Design;
13     using System.Drawing;
14     using System.Drawing.Drawing2D;
15     using System.Diagnostics;
16     using System.IO;
17     using System.Windows.Forms;
18     using System.Workflow.ComponentModel;
19     using System.Workflow.ComponentModel.Design;
20     using System.Runtime.Serialization;
21 
22     internal partial class StateDesigner : FreeformActivityDesigner
23     {
24         internal class DesignerLayoutConnectionPoint : ConnectionPoint
25         {
26             private CompositeActivity _eventHandler;
27             private DesignerEdges _designerEdges;
28 
DesignerLayoutConnectionPoint(ActivityDesigner associatedDesigner, int connectionIndex, CompositeActivity eventHandler, DesignerEdges designerEdges)29             public DesignerLayoutConnectionPoint(ActivityDesigner associatedDesigner, int connectionIndex, CompositeActivity eventHandler, DesignerEdges designerEdges)
30                 : base(associatedDesigner, designerEdges, connectionIndex)
31             {
32                 Debug.Assert(designerEdges == DesignerEdges.Left || designerEdges == DesignerEdges.Right);
33                 _eventHandler = eventHandler;
34                 _designerEdges = designerEdges;
35 
36             }
37 
38             public override Point Location
39             {
40                 get
41                 {
42                     Debug.Assert(this.DesignerEdges == DesignerEdges.Left || this.DesignerEdges == DesignerEdges.Right);
43                     DesignerLayout designerLayout = this.DesignerLayout;
44                     if (designerLayout == null)
45                         return Point.Empty;
46                     if (this.DesignerEdges == DesignerEdges.Left)
47                         return designerLayout.LeftConnectionPoint;
48                     else
49                         return designerLayout.RightConnectionPoint;
50                 }
51             }
52 
53             public DesignerLayout DesignerLayout
54             {
55                 get
56                 {
57                     DesignerLayout designerLayout;
58                     ((StateDesigner)this.AssociatedDesigner).DesignerLayouts.TryGetValue(this._eventHandler, out designerLayout);
59                     return designerLayout;
60                 }
61             }
62 
63             public DesignerEdges DesignerEdges
64             {
65                 get
66                 {
67                     return _designerEdges;
68                 }
69             }
70 
71             public CompositeActivity EventHandler
72             {
73                 get
74                 {
75                     return _eventHandler;
76                 }
77             }
78         }
79 
80         #region Layout class
81 
82         internal abstract class Layout
83         {
84             #region Fields
85             private List<Layout> _layouts = new List<Layout>();
86             private Point _location;
87             private Size _size;
88             private Size _minimumSize;
89             private ActivityDesigner _activityDesigner;
90             private Layout _mouseOverLayout;
91             #endregion Fields
92 
93             #region Constructor
Layout(ActivityDesigner activityDesigner)94             public Layout(ActivityDesigner activityDesigner)
95             {
96                 _activityDesigner = activityDesigner;
97             }
98             #endregion Constructor
99 
100             #region Events
101 
102             public event MouseEventHandler MouseMove;
103             public event MouseEventHandler MouseDown;
104             public event MouseEventHandler MouseUp;
105             public event EventHandler MouseEnter;
106             public event EventHandler MouseLeave;
107             public event MouseEventHandler MouseDoubleClick;
108 
109             #endregion
110 
111             #region Properties
112             public ActivityDesigner ActivityDesigner
113             {
114                 get
115                 {
116                     return _activityDesigner;
117                 }
118             }
119 
120             public Rectangle Bounds
121             {
122                 get
123                 {
124                     return new Rectangle(_location, _size);
125                 }
126             }
127 
128             public List<Layout> Layouts
129             {
130                 get
131                 {
132                     return _layouts;
133                 }
134             }
135 
136             public Point Location
137             {
138                 get
139                 {
140                     return _location;
141                 }
142                 set
143                 {
144                     _location = value;
145                 }
146             }
147 
148             public Size Size
149             {
150                 get
151                 {
152                     return _size;
153                 }
154                 set
155                 {
156                     _size = value;
157                 }
158             }
159 
160             public Layout MouseOverLayout
161             {
162                 get
163                 {
164                     return _mouseOverLayout;
165                 }
166                 set
167                 {
168                     if (value == _mouseOverLayout)
169                         return;
170 
171                     if (_mouseOverLayout != null)
172                         _mouseOverLayout.OnMouseLeave();
173 
174                     _mouseOverLayout = value;
175 
176                     if (value != null)
177                         value.OnMouseEnter();
178                 }
179             }
180 
181             public virtual Size MinimumSize
182             {
183                 get
184                 {
185                     return _minimumSize;
186                 }
187                 set
188                 {
189                     _minimumSize = value;
190                 }
191             }
192 
193             #endregion Properties
194 
195             #region Methods
196 
GetLayout(ActivityDesigner designer)197             public Layout GetLayout(ActivityDesigner designer)
198             {
199                 if (this.ActivityDesigner == designer)
200                     return this;
201 
202                 foreach (Layout layout in Layouts)
203                 {
204                     Layout found = layout.GetLayout(designer);
205                     if (found != null)
206                         return found;
207                 }
208                 return null;
209             }
210 
ResizeLayout(Size newSize)211             public virtual void ResizeLayout(Size newSize)
212             {
213                 _size = newSize;
214             }
215 
MoveLayout(Point newLocation)216             public virtual void MoveLayout(Point newLocation)
217             {
218                 if (newLocation == _location)
219                     return;
220 
221                 Point offset = new Point(_location.X - newLocation.X, _location.Y - newLocation.Y);
222                 foreach (Layout layout in _layouts)
223                 {
224                     Point currentLocation = layout.Location;
225                     Point newChildDesignerLocation = new Point(currentLocation.X - offset.X, currentLocation.Y - offset.Y);
226                     layout.MoveLayout(newChildDesignerLocation);
227                 }
228 
229                 _location = newLocation;
230             }
231 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)232             public virtual void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
233             {
234             }
235 
OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)236             public virtual void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
237             {
238             }
239 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)240             public virtual void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
241             {
242                 foreach (Layout layout in _layouts)
243                 {
244                     layout.OnPaint(graphics, designerTheme, ambientTheme);
245                 }
246             }
247 
OnMouseMove(MouseEventArgs e)248             public virtual void OnMouseMove(MouseEventArgs e)
249             {
250                 Layout layout = GetLayoutAt(e.X, e.Y);
251                 if (layout != this.MouseOverLayout)
252                 {
253                     this.MouseOverLayout = layout;
254                 }
255 
256                 if (this.MouseOverLayout == this)
257                 {
258                     if (this.MouseMove != null)
259                         this.MouseMove(this, e);
260                 }
261                 else
262                 {
263                     if (this.MouseOverLayout != null)
264                     {
265                         this.MouseOverLayout.OnMouseMove(e);
266                     }
267                 }
268             }
269 
OnMouseDown(MouseEventArgs e)270             public virtual void OnMouseDown(MouseEventArgs e)
271             {
272                 if (this.MouseOverLayout == this)
273                 {
274                     if (this.MouseDown != null)
275                         this.MouseDown(this, e);
276                 }
277                 else
278                 {
279                     if (this.MouseOverLayout != null)
280                     {
281                         this.MouseOverLayout.OnMouseDown(e);
282                     }
283                 }
284             }
285 
OnMouseUp(MouseEventArgs e)286             public virtual void OnMouseUp(MouseEventArgs e)
287             {
288                 if (this.MouseOverLayout == this)
289                 {
290                     if (this.MouseUp != null)
291                         this.MouseUp(this, e);
292                 }
293                 else
294                 {
295                     if (this.MouseOverLayout != null)
296                     {
297                         this.MouseOverLayout.OnMouseUp(e);
298                     }
299                 }
300 
301                 Layout layout = GetLayoutAt(e.X, e.Y);
302                 this.MouseOverLayout = layout;
303             }
304 
OnMouseEnter()305             public virtual void OnMouseEnter()
306             {
307                 if (this.MouseEnter != null)
308                     this.MouseEnter(this, EventArgs.Empty);
309             }
310 
OnMouseLeave()311             public virtual void OnMouseLeave()
312             {
313                 if (this.MouseOverLayout != this)
314                     this.MouseOverLayout = null;
315 
316                 if (this.MouseLeave != null)
317                     this.MouseLeave(this, EventArgs.Empty);
318             }
319 
OnMouseDoubleClick(MouseEventArgs e)320             public virtual void OnMouseDoubleClick(MouseEventArgs e)
321             {
322                 if (this.MouseOverLayout == this)
323                 {
324                     if (this.MouseDoubleClick != null)
325                         this.MouseDoubleClick(this, e);
326                 }
327                 else
328                 {
329                     if (this.MouseOverLayout != null)
330                     {
331                         this.MouseOverLayout.OnMouseDoubleClick(e);
332                     }
333                 }
334 
335                 Layout layout = GetLayoutAt(e.X, e.Y);
336                 this.MouseOverLayout = layout;
337             }
338 
Invalidate()339             public virtual void Invalidate()
340             {
341                 WorkflowView parentView = StateDesigner.GetService(_activityDesigner, typeof(WorkflowView)) as WorkflowView;
342                 if (parentView != null)
343                     parentView.InvalidateLogicalRectangle(this.Bounds);
344             }
345 
HitTest(Point point)346             public virtual HitTestInfo HitTest(Point point)
347             {
348                 HitTestInfo hitInfo = HitTestInfo.Nowhere;
349                 if (this.Bounds.Contains(point))
350                 {
351                     Layout layout = GetLayoutAt(point.X, point.Y);
352                     if (layout != this)
353                         hitInfo = layout.HitTest(point);
354                 }
355 
356                 return hitInfo;
357             }
358 
GetLayoutAt(int x, int y)359             private Layout GetLayoutAt(int x, int y)
360             {
361                 foreach (Layout layout in _layouts)
362                 {
363                     if (layout.Bounds.Contains(x, y))
364                     {
365                         return layout;
366                     }
367                 }
368 
369                 if (this.Bounds.Contains(x, y))
370                     return this;
371 
372                 return null;
373             }
374 
375             #endregion Methods
376         }
377 
378         #endregion Layout class
379 
380         #region DesignerLayoutBase class
381 
382         internal class DesignerLayoutBase : Layout
383         {
384             #region Fields
385             public const int ImagePadding = 4;
386             private Point _textLocation;
387             private Point _imageLocation;
388             private Size _textSize;
389             private Size _imageSize;
390             #endregion Fields
391 
392             #region Constructor
393 
DesignerLayoutBase(ActivityDesigner activityDesigner)394             public DesignerLayoutBase(ActivityDesigner activityDesigner)
395                 : base(activityDesigner)
396             {
397             }
398 
399             #endregion Constructor
400 
401             #region Properties
402 
403             public Rectangle ImageRectangle
404             {
405                 get
406                 {
407                     Rectangle rectangle = new Rectangle(_imageLocation, _imageSize);
408                     return StateMachineDesignerPaint.TrimRectangle(rectangle, Bounds);
409                 }
410             }
411 
412             public Rectangle TextRectangle
413             {
414                 get
415                 {
416                     Rectangle rectangle = new Rectangle(_textLocation, _textSize);
417                     return StateMachineDesignerPaint.TrimRectangle(rectangle, Bounds);
418                 }
419             }
420 
421             public string Text
422             {
423                 get
424                 {
425                     return this.ActivityDesigner.Activity.Name;
426                 }
427             }
428 
429             #endregion Properties
430 
431             #region Methods
432 
MoveLayout(Point newLocation)433             public override void MoveLayout(Point newLocation)
434             {
435                 Point offset = new Point(this.Location.X - newLocation.X, this.Location.Y - newLocation.Y);
436                 _textLocation = new Point(_textLocation.X - offset.X, _textLocation.Y - offset.Y);
437                 _imageLocation = new Point(_imageLocation.X - offset.X, _imageLocation.Y - offset.Y);
438                 base.MoveLayout(newLocation);
439             }
440 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)441             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
442             {
443                 base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
444 
445                 _imageSize = designerTheme.ImageSize;
446                 string text = this.Text;
447                 Font font = designerTheme.Font;
448                 _textSize = StateMachineDesignerPaint.MeasureString(graphics, font, text, StringAlignment.Near, Size.Empty);
449                 int width = _imageSize.Width + ImagePadding + _textSize.Width;
450                 width += ambientTheme.Margin.Width * 2;
451                 int height = Math.Max(_imageSize.Height, _textSize.Height);
452                 height += ambientTheme.Margin.Height;
453                 Size size = new Size(width, height);
454                 this.MinimumSize = size;
455                 this.Size = size;
456             }
457 
OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)458             public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
459             {
460                 base.OnLayoutPosition(graphics, designerTheme, ambientTheme);
461                 Point origin = this.Location;
462                 origin.X += ambientTheme.Margin.Width;
463                 origin.Y += ambientTheme.Margin.Height / 2;
464                 _imageLocation = origin;
465                 origin.X += _imageSize.Width + ImagePadding;
466                 _textLocation = origin;
467             }
468 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)469             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
470             {
471                 ActivityDesigner activityDesigner = this.ActivityDesigner;
472 
473                 Font font = designerTheme.Font;
474 
475                 Image image = StateDesigner.GetDesignerImage(activityDesigner);
476                 if (image != null)
477                     ActivityDesignerPaint.DrawImage(graphics, image, this.ImageRectangle, DesignerContentAlignment.Fill);
478 
479                 ActivityDesignerPaint.DrawText(graphics, font, this.Text, TextRectangle, StringAlignment.Near, ambientTheme.TextQuality, designerTheme.ForegroundBrush);
480             }
481 
482             #endregion Methods
483         }
484 
485         #endregion DesignerLayoutBase class
486 
487         #region DesignerLayout class
488 
489         internal class DesignerLayout : DesignerLayoutBase
490         {
DesignerLayout(ActivityDesigner activityDesigner)491             public DesignerLayout(ActivityDesigner activityDesigner)
492                 : base(activityDesigner)
493             {
494             }
495 
HitTest(Point point)496             public override HitTestInfo HitTest(Point point)
497             {
498                 HitTestInfo hitInfo = HitTestInfo.Nowhere;
499                 if (this.Bounds.Contains(point))
500                 {
501                     hitInfo = new HitTestInfo(this.ActivityDesigner, HitTestLocations.Designer | HitTestLocations.ActionArea);
502                 }
503 
504                 return hitInfo;
505             }
506 
507             public virtual Point LeftConnectionPoint
508             {
509                 get
510                 {
511                     Rectangle layoutBounds = this.Bounds;
512                     int midVert = layoutBounds.Y + (layoutBounds.Height / 2);
513                     Point point = new Point(layoutBounds.Left - 4, midVert);
514                     return point;
515                 }
516             }
517 
518             public virtual Point RightConnectionPoint
519             {
520                 get
521                 {
522                     Rectangle layoutBounds = this.Bounds;
523                     int midVert = layoutBounds.Y + (layoutBounds.Height / 2);
524                     Point point = new Point(layoutBounds.Right + 4, midVert);
525                     return point;
526                 }
527             }
528         }
529 
530         #endregion DesignerLayout class
531 
532         #region DesignerLinkLayout class
533 
534         private class DesignerLinkLayout : DesignerLayoutBase
535         {
536             #region Fields
537             private Cursor _previousCursor;
538             private bool _mouseOver;
539             private StateDesigner _parentStateDesigner;
540             #endregion Fields
541 
542             #region Constructor
DesignerLinkLayout(ActivityDesigner activityDesigner)543             public DesignerLinkLayout(ActivityDesigner activityDesigner)
544                 : base(activityDesigner)
545             {
546             }
547             #endregion Constructor
548 
549             #region Properties
550             public bool MouseOver
551             {
552                 get
553                 {
554                     return _mouseOver;
555                 }
556                 set
557                 {
558                     if (value == _mouseOver)
559                         return;
560 
561                     _mouseOver = value;
562                     Invalidate();
563                 }
564             }
565 
566             public StateDesigner ParentStateDesigner
567             {
568                 get
569                 {
570                     return _parentStateDesigner;
571                 }
572                 set
573                 {
574                     _parentStateDesigner = value;
575                 }
576             }
577             #endregion Properties
578 
579             #region Methods
580 
OnMouseEnter()581             public override void OnMouseEnter()
582             {
583                 base.OnMouseEnter();
584                 if (this.ParentStateDesigner != null)
585                 {
586                     _previousCursor = this.ParentStateDesigner.Cursor;
587                     this.ParentStateDesigner.Cursor = Cursors.Hand;
588                 }
589                 this.MouseOver = true;
590             }
591 
OnMouseLeave()592             public override void OnMouseLeave()
593             {
594                 base.OnMouseLeave();
595                 if (this.ParentStateDesigner != null)
596                 {
597                     this.ParentStateDesigner.Cursor = _previousCursor;
598                 }
599                 this.MouseOver = false;
600                 Invalidate();
601             }
602 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)603             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
604             {
605                 ActivityDesigner activityDesigner = this.ActivityDesigner;
606 
607                 if (this.MouseOver)
608                 {
609                     using (Font font = new Font(designerTheme.Font, FontStyle.Underline | designerTheme.Font.Style))
610                     {
611                         Image image = StateDesigner.GetDesignerImage(activityDesigner);
612                         if (image != null)
613                             ActivityDesignerPaint.DrawImage(graphics, image, this.ImageRectangle, DesignerContentAlignment.Fill);
614 
615                         ActivityDesignerPaint.DrawText(graphics, font, this.Text, TextRectangle, StringAlignment.Near, ambientTheme.TextQuality, designerTheme.ForegroundBrush);
616                     }
617                 }
618                 else
619                     base.OnPaint(graphics, designerTheme, ambientTheme);
620             }
621             #endregion Methods
622         }
623         #endregion DesignerLinkLayout class
624 
625         #region EventHandlersLayout class
626 
627         private class EventHandlersLayout : Layout
628         {
629             #region Fields
630             internal const int EventDrivenPadding = 8;
631             #endregion Fields
632 
633             #region Constructor
634 
EventHandlersLayout(ActivityDesigner activityDesigner)635             public EventHandlersLayout(ActivityDesigner activityDesigner)
636                 : base(activityDesigner)
637             {
638             }
639 
640             #endregion Constructor
641 
642             #region Methods
643 
ResizeLayout(Size newSize)644             public override void ResizeLayout(Size newSize)
645             {
646                 base.ResizeLayout(newSize);
647                 int maxEventDrivenWidth = newSize.Width - (EventDrivenPadding * 2);
648                 foreach (Layout layout in this.Layouts)
649                 {
650                     Size size = layout.Size;
651                     if (size.Width > maxEventDrivenWidth)
652                     {
653                         layout.ResizeLayout(new Size(maxEventDrivenWidth, size.Height));
654                     }
655                 }
656             }
657 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)658             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
659             {
660                 Size selectionSize = ambientTheme.SelectionSize;
661                 Size minimumSize = new Size();
662 
663                 foreach (Layout layout in Layouts)
664                 {
665                     layout.OnLayoutSize(graphics, designerTheme, ambientTheme, minimumSize);
666                     minimumSize.Height += layout.Size.Height;
667                     minimumSize.Height += selectionSize.Height;
668                     int layoutWidth = layout.Size.Width + 2 * (selectionSize.Width + ambientTheme.Margin.Width);
669                     minimumSize.Width = Math.Max(minimumSize.Width, layoutWidth);
670                 }
671 
672                 if (this.Layouts.Count > 0)
673                     minimumSize.Height += EventDrivenPadding;
674 
675                 this.MinimumSize = minimumSize;
676 
677                 Size size = new Size();
678                 size.Width = Math.Max(containerSize.Width, minimumSize.Height);
679                 size.Height = minimumSize.Height;
680                 this.Size = size;
681             }
682 
OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)683             public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
684             {
685                 Size selectionSize = ambientTheme.SelectionSize;
686                 int x = Location.X + EventDrivenPadding;
687                 int y = Location.Y + EventDrivenPadding;
688                 foreach (Layout layout in this.Layouts)
689                 {
690                     layout.Location = new Point(x, y);
691                     DesignerLayoutBase designerLayout = layout as DesignerLayoutBase;
692                     if (designerLayout != null)
693                         designerLayout.ActivityDesigner.Location = layout.Location;
694                     layout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
695                     y += layout.Size.Height + selectionSize.Height;
696                 }
697             }
698 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)699             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
700             {
701                 base.OnPaint(graphics, designerTheme, ambientTheme);
702 
703                 StateDesigner stateDesigner = (StateDesigner)this.ActivityDesigner;
704                 ContainedDesignersParser parser = stateDesigner._designersParser;
705                 // we only draw the separation line
706                 // if we have at least one event driven and one state
707                 if ((parser.EventDrivenDesigners.Count > 0 || parser.StateInitializationDesigners.Count > 0 || parser.StateFinalizationDesigners.Count > 0) &&
708                     (parser.StateDesigners.Count > 0 || parser.LeafStateDesigners.Count > 0))
709                 {
710                     Rectangle bounds = this.Bounds;
711                     graphics.DrawLine(designerTheme.BorderPen, bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom);
712                 }
713             }
714 
715             #endregion
716         }
717 
718         #endregion
719 
720         #region BreadCrumbBarLayout class
721 
722         private class BreadCrumbBarLayout : Layout
723         {
724             #region Fields
725 
726             private const string BreadCrumbSeparator = " : ";
727             private Size _breadCrumbSeparatorSize;
728 
729             #endregion Fields
730 
731             #region Constructor
732 
BreadCrumbBarLayout(ActivityDesigner activityDesigner)733             public BreadCrumbBarLayout(ActivityDesigner activityDesigner)
734                 : base(activityDesigner)
735             {
736             }
737 
738             #endregion Constructor
739 
740             #region Methods
741 
InitializeLayouts()742             private void InitializeLayouts()
743             {
744                 this.Layouts.Clear();
745                 StateDesigner rootStateDesigner = (StateDesigner)this.ActivityDesigner;
746                 StateDesigner currentDesigner = rootStateDesigner;
747                 while (currentDesigner != null)
748                 {
749                     DesignerLinkLayout layout = currentDesigner.InlineLayout;
750                     layout.ParentStateDesigner = rootStateDesigner;
751                     this.Layouts.Add(currentDesigner.InlineLayout);
752                     currentDesigner = currentDesigner.ActiveDesigner as StateDesigner;
753                 }
754             }
755 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)756             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
757             {
758                 base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
759 
760                 InitializeLayouts();
761 
762                 CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
763                 if (compositeDesignerTheme == null)
764                     return;
765 
766                 Font font = designerTheme.BoldFont;
767                 _breadCrumbSeparatorSize = StateMachineDesignerPaint.MeasureString(graphics, font, BreadCrumbSeparator, StringAlignment.Near, Size.Empty);
768                 Size size = Size.Empty;
769 
770                 foreach (Layout layout in Layouts)
771                 {
772                     layout.OnLayoutSize(graphics, compositeDesignerTheme, ambientTheme, size);
773                     size.Width += layout.Size.Width + _breadCrumbSeparatorSize.Width;
774                     size.Height = Math.Max(size.Height, layout.Size.Height);
775                 }
776 
777                 this.MinimumSize = size;
778                 this.Size = size;
779             }
780 
OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)781             public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
782             {
783                 Point location = this.Location;
784                 foreach (Layout layout in this.Layouts)
785                 {
786                     layout.Location = location;
787                     layout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
788                     location.X += layout.Size.Width + _breadCrumbSeparatorSize.Width;
789                 }
790             }
791 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)792             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
793             {
794                 if (Layouts.Count == 0)
795                     return;
796 
797                 Font font = designerTheme.BoldFont;
798                 TextQuality textQuality = ambientTheme.TextQuality;
799                 Brush brush = designerTheme.ForegroundBrush;
800 
801                 List<Layout> layouts = this.Layouts;
802                 Layout layout;
803                 for (int i = 0; i < layouts.Count - 1; i++)
804                 {
805                     layout = layouts[i];
806                     layout.OnPaint(graphics, designerTheme, ambientTheme);
807 
808                     Rectangle separatorRectangle = new Rectangle(
809                         layout.Bounds.Right,
810                         layout.Location.Y,
811                         _breadCrumbSeparatorSize.Width,
812                         _breadCrumbSeparatorSize.Height);
813 
814                     ActivityDesignerPaint.DrawText(graphics, font, BreadCrumbSeparator, separatorRectangle,
815                         StringAlignment.Near, textQuality, brush);
816                 }
817 
818                 // draw the last one
819                 layout = layouts[layouts.Count - 1];
820                 layout.OnPaint(graphics, designerTheme, ambientTheme);
821             }
822 
823             #endregion Methods
824         }
825 
826         #endregion
827 
828         #region TextLayout class
829 
830         private class TextLayout : Layout
831         {
832             #region Constructor
833 
TextLayout(ActivityDesigner activityDesigner)834             public TextLayout(ActivityDesigner activityDesigner)
835                 : base(activityDesigner)
836             {
837             }
838 
839             #endregion Constructor
840 
841             #region Methods
842 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)843             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
844             {
845                 base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
846 
847                 CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
848                 string text = this.ActivityDesigner.Text;
849                 Size size = Size.Empty;
850                 if (compositeDesignerTheme != null && !String.IsNullOrEmpty(text))
851                 {
852                     size = StateMachineDesignerPaint.MeasureString(graphics, compositeDesignerTheme.Font, text, StringAlignment.Center, Size.Empty);
853                 }
854                 this.MinimumSize = size;
855                 this.Size = size;
856             }
857 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)858             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
859             {
860                 string text = this.ActivityDesigner.Text;
861                 if (String.IsNullOrEmpty(text))
862                     return;
863 
864                 Font font = designerTheme.Font;
865                 ActivityDesignerPaint.DrawText(graphics, font, text, this.Bounds, StringAlignment.Near, ambientTheme.TextQuality, designerTheme.ForegroundBrush);
866             }
867 
868             #endregion Methods
869         }
870 
871         #endregion
872 
873         #region ImageLayout class
874 
875         private class ImageLayout : Layout
876         {
877             #region Constructor
878 
ImageLayout(ActivityDesigner activityDesigner)879             public ImageLayout(ActivityDesigner activityDesigner)
880                 : base(activityDesigner)
881             {
882             }
883 
884             #endregion Constructor
885 
886             #region Methods
887 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)888             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
889             {
890                 base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
891 
892                 CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
893                 Size size = Size.Empty;
894                 if (this.ActivityDesigner.Image != null && compositeDesignerTheme != null)
895                 {
896                     size = designerTheme.ImageSize;
897                 }
898                 this.MinimumSize = size;
899                 this.Size = size;
900             }
901 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)902             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
903             {
904                 Image image = this.ActivityDesigner.Image;
905                 if (image != null)
906                     ActivityDesignerPaint.DrawImage(graphics, image, this.Bounds, DesignerContentAlignment.Fill);
907             }
908 
909             #endregion Methods
910         }
911 
912         #endregion
913 
914         #region TitleBarLayout class
915 
916         private class TitleBarLayout : Layout
917         {
918             #region Fields
919 
920             private TextLayout _textLayout;
921             private ImageLayout _imageLayout;
922             private const int Padding = 4;
923 
924             #endregion Fields
925 
926             #region Constructor
927 
TitleBarLayout(ActivityDesigner activityDesigner)928             public TitleBarLayout(ActivityDesigner activityDesigner)
929                 : base(activityDesigner)
930             {
931                 _textLayout = new TextLayout(activityDesigner);
932                 this.Layouts.Add(_textLayout);
933                 _imageLayout = new ImageLayout(activityDesigner);
934                 this.Layouts.Add(_imageLayout);
935             }
936 
937             #endregion Constructor
938 
939             #region Properties
940 
941             public TextLayout TextLayout
942             {
943                 get
944                 {
945                     return _textLayout;
946                 }
947             }
948 
949             public ImageLayout ImageLayout
950             {
951                 get
952                 {
953                     return _imageLayout;
954                 }
955             }
956 
957             #endregion Properties
958 
959             #region Methods
960 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)961             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
962             {
963                 base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
964 
965                 Size minimumSize = new Size();
966                 _textLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, Size.Empty);
967                 _imageLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, Size.Empty);
968 
969                 minimumSize.Width = designerTheme.BorderWidth * 2 + 10 + _textLayout.Size.Width + _imageLayout.Size.Width;
970                 minimumSize.Height = Math.Max(_textLayout.Size.Height, _imageLayout.Size.Height);
971                 minimumSize.Height += designerTheme.BorderWidth * 2 + 4;
972 
973                 this.MinimumSize = minimumSize;
974                 Size size = minimumSize;
975                 size.Width = Math.Max(minimumSize.Width, containerSize.Width);
976                 this.Size = size;
977             }
978 
OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)979             public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
980             {
981                 Size margin = WorkflowTheme.CurrentTheme.AmbientTheme.Margin;
982                 Point origin = this.Location;
983                 origin.X += margin.Width;
984                 origin.Y += 2;
985 
986                 _imageLayout.Location = origin;
987 
988                 CalculateTextLayout();
989             }
990 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)991             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
992             {
993                 Rectangle rectangle = this.Bounds;
994 
995                 Brush backgroundBrush = designerTheme.GetBackgroundBrush(this.Bounds);
996                 graphics.FillRectangle(backgroundBrush, rectangle);
997 
998                 Color color1;
999                 Color color2;
1000                 StateActivity state = (StateActivity)this.ActivityDesigner.Activity;
1001                 if (StateMachineHelpers.IsLeafState(state))
1002                 {
1003                     color1 = Color.FromArgb(32, designerTheme.BorderColor);
1004                     color2 = Color.FromArgb(160, designerTheme.BorderColor);
1005                 }
1006                 else
1007                 {
1008                     if (StateMachineHelpers.IsRootState(state))
1009                     {
1010                         color1 = Color.Empty;
1011                         color2 = Color.FromArgb(128, designerTheme.BorderColor);
1012                     }
1013                     else
1014                     {
1015                         color1 = Color.FromArgb(16, designerTheme.BorderColor);
1016                         color2 = Color.FromArgb(16, designerTheme.BorderColor);
1017                     }
1018                 }
1019 
1020                 if (rectangle.Width > 0 && rectangle.Height > 0)
1021                 {
1022                     using (Brush linearGradientBrush = new LinearGradientBrush(rectangle, color1, color2, LinearGradientMode.Vertical))
1023                     {
1024                         graphics.FillRectangle(linearGradientBrush, rectangle);
1025                         graphics.DrawLine(designerTheme.BorderPen, rectangle.Left, rectangle.Bottom, rectangle.Right, rectangle.Bottom);
1026                     }
1027                 }
1028 
1029                 base.OnPaint(graphics, designerTheme, ambientTheme);
1030             }
1031 
ResizeLayout(Size newSize)1032             public override void ResizeLayout(Size newSize)
1033             {
1034                 base.ResizeLayout(newSize);
1035                 CalculateTextLayout();
1036             }
1037 
CalculateTextLayout()1038             private void CalculateTextLayout()
1039             {
1040                 Size margin = WorkflowTheme.CurrentTheme.AmbientTheme.Margin;
1041 
1042                 int minX = _imageLayout.Bounds.Right + Padding;
1043 
1044                 int maxStringWidth = _textLayout.Size.Width;
1045                 int xPos = (this.Location.X + this.Size.Width / 2 - maxStringWidth / 2);
1046                 if (xPos < minX)
1047                     xPos = minX;
1048 
1049                 if ((xPos + maxStringWidth) > (this.Bounds.Right - margin.Width))
1050                     maxStringWidth = (this.Bounds.Right - margin.Width) - xPos;
1051 
1052                 _textLayout.Location = new Point(xPos, this.Location.Y + margin.Height);
1053                 _textLayout.Size = new Size(maxStringWidth, _textLayout.Size.Height);
1054             }
1055 
1056             #endregion Methods
1057         }
1058 
1059         #endregion
1060 
1061         #region StatesLayout class
1062 
1063         private class StatesLayout : Layout
1064         {
1065             #region Fields
1066             private const int StatePadding = 16;
1067             private static readonly Size RealMinimumSize = new Size(160, 80);
1068             private TitleBarLayout _titleBarLayout;
1069             private EventHandlersLayout _eventHandlersLayout;
1070             #endregion Fields
1071 
1072             #region Constructor
1073 
StatesLayout( ActivityDesigner activityDesigner, TitleBarLayout titleBarLayout, EventHandlersLayout eventHandlersLayout)1074             public StatesLayout(
1075                 ActivityDesigner activityDesigner,
1076                 TitleBarLayout titleBarLayout,
1077                 EventHandlersLayout eventHandlersLayout)
1078                 : base(activityDesigner)
1079             {
1080                 _titleBarLayout = titleBarLayout;
1081                 this.Layouts.Add(titleBarLayout);
1082                 _eventHandlersLayout = eventHandlersLayout;
1083                 this.Layouts.Add(eventHandlersLayout);
1084             }
1085 
1086             #endregion Constructor
1087 
1088             #region Properties
1089 
1090             private StateDesigner StateDesigner
1091             {
1092                 get
1093                 {
1094                     return (StateDesigner)this.ActivityDesigner;
1095                 }
1096             }
1097 
1098             public override Size MinimumSize
1099             {
1100                 get
1101                 {
1102                     Size minimumSize = base.MinimumSize;
1103                     minimumSize.Width = Math.Max(minimumSize.Width, RealMinimumSize.Width);
1104                     minimumSize.Height = Math.Max(minimumSize.Height, RealMinimumSize.Height);
1105                     return minimumSize;
1106                 }
1107             }
1108 
1109             public EventHandlersLayout EventHandlersLayout
1110             {
1111                 get
1112                 {
1113                     return _eventHandlersLayout;
1114                 }
1115             }
1116 
1117             #endregion Properties
1118 
1119             #region Methods
1120 
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)1121             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
1122             {
1123                 base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
1124 
1125                 CompositeDesignerTheme compositeDesignerTheme = (CompositeDesignerTheme)designerTheme;
1126 
1127                 Size size = containerSize;
1128 
1129                 _titleBarLayout.OnLayoutSize(graphics, compositeDesignerTheme, ambientTheme, size);
1130                 _eventHandlersLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
1131 
1132                 int minWidth = Math.Max(_titleBarLayout.MinimumSize.Width, _eventHandlersLayout.MinimumSize.Width);
1133                 int minHeight = _titleBarLayout.MinimumSize.Height + _eventHandlersLayout.MinimumSize.Height;
1134                 this.MinimumSize = new Size(minWidth, minHeight);
1135 
1136                 size.Width = Math.Max(minWidth, size.Width);
1137                 size.Height = Math.Max(minHeight, size.Height);
1138 
1139                 if (this.StateDesigner.NeedsAutoLayout)
1140                 {
1141                     int maximumX = size.Width;
1142                     int maximumY = _titleBarLayout.Size.Height +
1143                         _eventHandlersLayout.Size.Height +
1144                         DefaultStateDesignerAutoLayoutDistance;
1145 
1146                     bool containsStates = false;
1147 
1148                     foreach (ActivityDesigner designer in this.StateDesigner.ContainedDesigners)
1149                     {
1150                         if (!this.StateDesigner.IsContainedDesignerVisible(designer))
1151                             continue;
1152 
1153                         StateDesigner stateDesigner = designer as StateDesigner;
1154                         if (stateDesigner == null)
1155                             continue;
1156 
1157                         containsStates = true;
1158 
1159                         maximumX = Math.Max(maximumX, designer.Size.Width);
1160                         maximumY += designer.Size.Height + DefaultStateDesignerAutoLayoutDistance;
1161                     }
1162 
1163                     if (containsStates)
1164                     {
1165                         // Add some extra padding to take into account for the AutoSize growth
1166                         maximumY += DefaultStateDesignerAutoLayoutDistance * 2;
1167                     }
1168 
1169                     size = new Size(maximumX, maximumY);
1170                 }
1171 
1172                 _titleBarLayout.ResizeLayout(new Size(size.Width, _titleBarLayout.Size.Height));
1173 
1174                 this.Size = size;
1175             }
1176 
OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)1177             public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
1178             {
1179                 _titleBarLayout.Location = this.Location;
1180                 _titleBarLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
1181 
1182                 int x = this.Location.X;
1183                 int y = _titleBarLayout.Bounds.Bottom + 1;
1184 
1185                 _eventHandlersLayout.Location = new Point(x, y);
1186                 _eventHandlersLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
1187             }
1188 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)1189             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
1190             {
1191                 GraphicsPath path = StateMachineDesignerPaint.GetDesignerPath(this.ActivityDesigner, this.Bounds, designerTheme);
1192                 Brush backgroundBrush = designerTheme.GetBackgroundBrush(this.Bounds);
1193                 graphics.FillPath(backgroundBrush, path);
1194 
1195                 base.OnPaint(graphics, designerTheme, ambientTheme);
1196 
1197                 if (ambientTheme.ShowDesignerBorder)
1198                     graphics.DrawPath(designerTheme.BorderPen, path);
1199 
1200                 if (this.StateDesigner.ContainedDesigners.Count == 0 &&
1201                     !this.StateDesigner.IsStateCustomActivity)
1202                 {
1203                     Point location = new Point(this.Location.X, _titleBarLayout.Bounds.Bottom);
1204                     Size size = new Size(this.Size.Width, this.Size.Height - _titleBarLayout.Bounds.Height);
1205                     Rectangle rectangle = new Rectangle(location, size);
1206                     rectangle.Inflate(-1, -1);
1207 
1208                     StateActivity state = (StateActivity)this.StateDesigner.Activity;
1209                     if (StateMachineHelpers.IsLeafState(state) &&
1210                         StateMachineHelpers.IsCompletedState(state))
1211                         return;
1212 
1213                     if (this.StateDesigner.DragDropActive)
1214                     {
1215                         Color color = Color.FromArgb(64, designerTheme.ForeColor);
1216                         using (SolidBrush brush = new SolidBrush(color))
1217                         {
1218                             ActivityDesignerPaint.DrawText(
1219                                 graphics,
1220                                 designerTheme.Font,
1221                                 this.StateDesigner.HelpText,
1222                                 rectangle,
1223                                 StringAlignment.Center,
1224                                 ambientTheme.TextQuality,
1225                                 brush);
1226                         }
1227                     }
1228                     else
1229                     {
1230                         ActivityDesignerPaint.DrawText(
1231                             graphics,
1232                             designerTheme.Font,
1233                             this.StateDesigner.HelpText,
1234                             rectangle,
1235                             StringAlignment.Center,
1236                             ambientTheme.TextQuality,
1237                             designerTheme.ForegroundBrush);
1238                     }
1239                 }
1240             }
1241 
ResizeLayout(Size newSize)1242             public override void ResizeLayout(Size newSize)
1243             {
1244                 _eventHandlersLayout.ResizeLayout(new Size(newSize.Width, _eventHandlersLayout.Size.Height));
1245                 _titleBarLayout.ResizeLayout(new Size(newSize.Width, _titleBarLayout.Size.Height));
1246                 base.ResizeLayout(newSize);
1247             }
1248 
1249             #endregion Methods
1250         }
1251 
1252         #endregion StatesLayout class
1253 
1254         #region EventDrivenLayout class
1255 
1256         private class EventDrivenLayout : Layout
1257         {
1258             #region Fields
1259 
1260             private BreadCrumbBarLayout _breadCrumbBarLayout;
1261             private TitleBarLayout _titleBarLayout;
1262             private DesignerLinkLayout _designerLayout;
1263             private const int ActiveDesignerPadding = 16;
1264             #endregion
1265 
1266             #region Constructor
EventDrivenLayout(ActivityDesigner activityDesigner, TitleBarLayout titleBarLayout)1267             public EventDrivenLayout(ActivityDesigner activityDesigner, TitleBarLayout titleBarLayout)
1268                 : base(activityDesigner)
1269             {
1270                 _breadCrumbBarLayout = new BreadCrumbBarLayout(activityDesigner);
1271                 _designerLayout = new DesignerLinkLayout(activityDesigner);
1272                 StateDesigner stateDesigner = activityDesigner as StateDesigner;
1273                 if (stateDesigner != null)
1274                 {
1275                     _designerLayout.ParentStateDesigner = stateDesigner;
1276                     _designerLayout.MouseDown += new MouseEventHandler(stateDesigner.StateDesignerLinkMouseDown);
1277                 }
1278                 _titleBarLayout = titleBarLayout;
1279             }
1280 
InitializeLayout()1281             private void InitializeLayout()
1282             {
1283                 this.Layouts.Clear();
1284                 if (this.StateDesigner.IsRootStateDesigner)
1285                 {
1286                     // we only display the title bar and
1287                     // the bread crumb bar at the top most level
1288                     this.Layouts.Add(_titleBarLayout);
1289                     this.Layouts.Add(_breadCrumbBarLayout);
1290                 }
1291                 else
1292                 {
1293                     this.Layouts.Add(_designerLayout);
1294                 }
1295             }
1296 
1297             #endregion
1298 
1299             #region Properties
1300 
1301             private StateDesigner StateDesigner
1302             {
1303                 get
1304                 {
1305                     return (StateDesigner)this.ActivityDesigner;
1306                 }
1307             }
1308 
1309             #endregion Properties
1310 
1311             #region Methods
OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)1312             public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
1313             {
1314                 base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
1315 
1316                 InitializeLayout();
1317 
1318                 Size size = containerSize;
1319                 Size minSize = this.StateDesigner.MinimumSize;
1320                 size.Width = Math.Max(size.Width, minSize.Width);
1321                 size.Height = Math.Max(size.Height, minSize.Height);
1322 
1323                 ActivityDesigner activeDesigner = this.StateDesigner.ActiveDesigner;
1324                 Size activeDesignerSize = activeDesigner.Size;
1325 
1326                 if (this.StateDesigner.IsRootStateDesigner)
1327                 {
1328                     _titleBarLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
1329                     _breadCrumbBarLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
1330 
1331                     size.Width = Math.Max(size.Width, activeDesignerSize.Width + ActiveDesignerPadding * 2);
1332                     size.Width = Math.Max(size.Width, _titleBarLayout.Size.Width);
1333                     size.Width = Math.Max(size.Width, _breadCrumbBarLayout.Size.Width);
1334 
1335                     int minHeight =
1336                         activeDesignerSize.Height +
1337                         _titleBarLayout.Size.Height +
1338                         _breadCrumbBarLayout.Size.Height +
1339                         ActiveDesignerPadding * 3 +
1340                         ambientTheme.SelectionSize.Height * 2;
1341                     size.Height = Math.Max(size.Height, minHeight);
1342                     _titleBarLayout.ResizeLayout(new Size(size.Width, _titleBarLayout.Size.Height));
1343                 }
1344                 else
1345                 {
1346                     _designerLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
1347                     size.Width = Math.Max(size.Width, activeDesigner.Size.Width + ActiveDesignerPadding * 2);
1348                     size.Width = Math.Max(size.Width, _designerLayout.Size.Width);
1349                     size.Height = Math.Max(size.Height, activeDesigner.Size.Height + ActiveDesignerPadding * 2 + _designerLayout.Size.Height + ambientTheme.SelectionSize.Height * 2);
1350                 }
1351 
1352                 this.MinimumSize = size;
1353                 this.Size = size;
1354             }
1355 
OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)1356             public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
1357             {
1358                 CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
1359                 if (compositeDesignerTheme == null)
1360                     return;
1361 
1362                 Rectangle bounds = this.Bounds;
1363                 Point origin = bounds.Location;
1364                 if (this.StateDesigner.IsRootStateDesigner)
1365                 {
1366                     _titleBarLayout.Location = origin;
1367                     _titleBarLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
1368                     origin.X += ActiveDesignerPadding;
1369                     origin.Y += _titleBarLayout.Size.Height + ActiveDesignerPadding;
1370                     _breadCrumbBarLayout.Location = origin;
1371                     _breadCrumbBarLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
1372                     origin.Y += _breadCrumbBarLayout.Size.Height + ActiveDesignerPadding;
1373                 }
1374                 else
1375                 {
1376                     Point designerLayoutLocation = new Point(
1377                         bounds.Left + (bounds.Width - _designerLayout.Size.Width) / 2,
1378                         bounds.Top + ambientTheme.SelectionSize.Height);
1379                     _designerLayout.Location = designerLayoutLocation;
1380                     _designerLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
1381                     origin.Y = _designerLayout.Bounds.Bottom + ambientTheme.SelectionSize.Height + ActiveDesignerPadding;
1382                 }
1383 
1384                 Size activeDesignerSize = this.StateDesigner.ActiveDesigner.Size;
1385                 origin.X = bounds.Left + (bounds.Width - activeDesignerSize.Width) / 2;
1386 
1387                 this.StateDesigner.ActiveDesigner.Location = origin;
1388             }
1389 
OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)1390             public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
1391             {
1392                 GraphicsPath path = StateMachineDesignerPaint.GetDesignerPath(this.ActivityDesigner, this.Bounds, designerTheme);
1393                 Brush backgroundBrush = designerTheme.GetBackgroundBrush(this.Bounds);
1394                 graphics.FillPath(backgroundBrush, path);
1395 
1396                 base.OnPaint(graphics, designerTheme, ambientTheme);
1397 
1398                 if (ambientTheme.ShowDesignerBorder)
1399                     graphics.DrawPath(designerTheme.BorderPen, path);
1400             }
1401 
ResizeLayout(Size newSize)1402             public override void ResizeLayout(Size newSize)
1403             {
1404                 if (this.StateDesigner.IsRootStateDesigner)
1405                 {
1406                     _titleBarLayout.ResizeLayout(new Size(newSize.Width, _titleBarLayout.Size.Height));
1407                 }
1408                 base.ResizeLayout(newSize);
1409             }
1410 
1411             #endregion Methods
1412         }
1413 
1414         #endregion
1415     }
1416 }
1417