|
namespace System.Workflow.Activities
{
using System;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.CodeDom;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Runtime.Serialization;
internal partial class StateDesigner : FreeformActivityDesigner
{
internal class DesignerLayoutConnectionPoint : ConnectionPoint
{
private CompositeActivity _eventHandler;
private DesignerEdges _designerEdges;
public DesignerLayoutConnectionPoint(ActivityDesigner associatedDesigner, int connectionIndex, CompositeActivity eventHandler, DesignerEdges designerEdges)
: base(associatedDesigner, designerEdges, connectionIndex)
{
Debug.Assert(designerEdges == DesignerEdges.Left || designerEdges == DesignerEdges.Right);
_eventHandler = eventHandler;
_designerEdges = designerEdges;
}
public override Point Location
{
get
{
Debug.Assert(this.DesignerEdges == DesignerEdges.Left || this.DesignerEdges == DesignerEdges.Right);
DesignerLayout designerLayout = this.DesignerLayout;
if (designerLayout == null)
return Point.Empty;
if (this.DesignerEdges == DesignerEdges.Left)
return designerLayout.LeftConnectionPoint;
else
return designerLayout.RightConnectionPoint;
}
}
public DesignerLayout DesignerLayout
{
get
{
DesignerLayout designerLayout;
((StateDesigner)this.AssociatedDesigner).DesignerLayouts.TryGetValue(this._eventHandler, out designerLayout);
return designerLayout;
}
}
public DesignerEdges DesignerEdges
{
get
{
return _designerEdges;
}
}
public CompositeActivity EventHandler
{
get
{
return _eventHandler;
}
}
}
#region Layout class
internal abstract class Layout
{
#region Fields
private List<Layout> _layouts = new List<Layout>();
private Point _location;
private Size _size;
private Size _minimumSize;
private ActivityDesigner _activityDesigner;
private Layout _mouseOverLayout;
#endregion Fields
#region Constructor
public Layout(ActivityDesigner activityDesigner)
{
_activityDesigner = activityDesigner;
}
#endregion Constructor
#region Events
public event MouseEventHandler MouseMove;
public event MouseEventHandler MouseDown;
public event MouseEventHandler MouseUp;
public event EventHandler MouseEnter;
public event EventHandler MouseLeave;
public event MouseEventHandler MouseDoubleClick;
#endregion
#region Properties
public ActivityDesigner ActivityDesigner
{
get
{
return _activityDesigner;
}
}
public Rectangle Bounds
{
get
{
return new Rectangle(_location, _size);
}
}
public List<Layout> Layouts
{
get
{
return _layouts;
}
}
public Point Location
{
get
{
return _location;
}
set
{
_location = value;
}
}
public Size Size
{
get
{
return _size;
}
set
{
_size = value;
}
}
public Layout MouseOverLayout
{
get
{
return _mouseOverLayout;
}
set
{
if (value == _mouseOverLayout)
return;
if (_mouseOverLayout != null)
_mouseOverLayout.OnMouseLeave();
_mouseOverLayout = value;
if (value != null)
value.OnMouseEnter();
}
}
public virtual Size MinimumSize
{
get
{
return _minimumSize;
}
set
{
_minimumSize = value;
}
}
#endregion Properties
#region Methods
public Layout GetLayout(ActivityDesigner designer)
{
if (this.ActivityDesigner == designer)
return this;
foreach (Layout layout in Layouts)
{
Layout found = layout.GetLayout(designer);
if (found != null)
return found;
}
return null;
}
public virtual void ResizeLayout(Size newSize)
{
_size = newSize;
}
public virtual void MoveLayout(Point newLocation)
{
if (newLocation == _location)
return;
Point offset = new Point(_location.X - newLocation.X, _location.Y - newLocation.Y);
foreach (Layout layout in _layouts)
{
Point currentLocation = layout.Location;
Point newChildDesignerLocation = new Point(currentLocation.X - offset.X, currentLocation.Y - offset.Y);
layout.MoveLayout(newChildDesignerLocation);
}
_location = newLocation;
}
public virtual void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
}
public virtual void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
}
public virtual void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
foreach (Layout layout in _layouts)
{
layout.OnPaint(graphics, designerTheme, ambientTheme);
}
}
public virtual void OnMouseMove(MouseEventArgs e)
{
Layout layout = GetLayoutAt(e.X, e.Y);
if (layout != this.MouseOverLayout)
{
this.MouseOverLayout = layout;
}
if (this.MouseOverLayout == this)
{
if (this.MouseMove != null)
this.MouseMove(this, e);
}
else
{
if (this.MouseOverLayout != null)
{
this.MouseOverLayout.OnMouseMove(e);
}
}
}
public virtual void OnMouseDown(MouseEventArgs e)
{
if (this.MouseOverLayout == this)
{
if (this.MouseDown != null)
this.MouseDown(this, e);
}
else
{
if (this.MouseOverLayout != null)
{
this.MouseOverLayout.OnMouseDown(e);
}
}
}
public virtual void OnMouseUp(MouseEventArgs e)
{
if (this.MouseOverLayout == this)
{
if (this.MouseUp != null)
this.MouseUp(this, e);
}
else
{
if (this.MouseOverLayout != null)
{
this.MouseOverLayout.OnMouseUp(e);
}
}
Layout layout = GetLayoutAt(e.X, e.Y);
this.MouseOverLayout = layout;
}
public virtual void OnMouseEnter()
{
if (this.MouseEnter != null)
this.MouseEnter(this, EventArgs.Empty);
}
public virtual void OnMouseLeave()
{
if (this.MouseOverLayout != this)
this.MouseOverLayout = null;
if (this.MouseLeave != null)
this.MouseLeave(this, EventArgs.Empty);
}
public virtual void OnMouseDoubleClick(MouseEventArgs e)
{
if (this.MouseOverLayout == this)
{
if (this.MouseDoubleClick != null)
this.MouseDoubleClick(this, e);
}
else
{
if (this.MouseOverLayout != null)
{
this.MouseOverLayout.OnMouseDoubleClick(e);
}
}
Layout layout = GetLayoutAt(e.X, e.Y);
this.MouseOverLayout = layout;
}
public virtual void Invalidate()
{
WorkflowView parentView = StateDesigner.GetService(_activityDesigner, typeof(WorkflowView)) as WorkflowView;
if (parentView != null)
parentView.InvalidateLogicalRectangle(this.Bounds);
}
public virtual HitTestInfo HitTest(Point point)
{
HitTestInfo hitInfo = HitTestInfo.Nowhere;
if (this.Bounds.Contains(point))
{
Layout layout = GetLayoutAt(point.X, point.Y);
if (layout != this)
hitInfo = layout.HitTest(point);
}
return hitInfo;
}
private Layout GetLayoutAt(int x, int y)
{
foreach (Layout layout in _layouts)
{
if (layout.Bounds.Contains(x, y))
{
return layout;
}
}
if (this.Bounds.Contains(x, y))
return this;
return null;
}
#endregion Methods
}
#endregion Layout class
#region DesignerLayoutBase class
internal class DesignerLayoutBase : Layout
{
#region Fields
public const int ImagePadding = 4;
private Point _textLocation;
private Point _imageLocation;
private Size _textSize;
private Size _imageSize;
#endregion Fields
#region Constructor
public DesignerLayoutBase(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
}
#endregion Constructor
#region Properties
public Rectangle ImageRectangle
{
get
{
Rectangle rectangle = new Rectangle(_imageLocation, _imageSize);
return StateMachineDesignerPaint.TrimRectangle(rectangle, Bounds);
}
}
public Rectangle TextRectangle
{
get
{
Rectangle rectangle = new Rectangle(_textLocation, _textSize);
return StateMachineDesignerPaint.TrimRectangle(rectangle, Bounds);
}
}
public string Text
{
get
{
return this.ActivityDesigner.Activity.Name;
}
}
#endregion Properties
#region Methods
public override void MoveLayout(Point newLocation)
{
Point offset = new Point(this.Location.X - newLocation.X, this.Location.Y - newLocation.Y);
_textLocation = new Point(_textLocation.X - offset.X, _textLocation.Y - offset.Y);
_imageLocation = new Point(_imageLocation.X - offset.X, _imageLocation.Y - offset.Y);
base.MoveLayout(newLocation);
}
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
_imageSize = designerTheme.ImageSize;
string text = this.Text;
Font font = designerTheme.Font;
_textSize = StateMachineDesignerPaint.MeasureString(graphics, font, text, StringAlignment.Near, Size.Empty);
int width = _imageSize.Width + ImagePadding + _textSize.Width;
width += ambientTheme.Margin.Width * 2;
int height = Math.Max(_imageSize.Height, _textSize.Height);
height += ambientTheme.Margin.Height;
Size size = new Size(width, height);
this.MinimumSize = size;
this.Size = size;
}
public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
base.OnLayoutPosition(graphics, designerTheme, ambientTheme);
Point origin = this.Location;
origin.X += ambientTheme.Margin.Width;
origin.Y += ambientTheme.Margin.Height / 2;
_imageLocation = origin;
origin.X += _imageSize.Width + ImagePadding;
_textLocation = origin;
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
ActivityDesigner activityDesigner = this.ActivityDesigner;
Font font = designerTheme.Font;
Image image = StateDesigner.GetDesignerImage(activityDesigner);
if (image != null)
ActivityDesignerPaint.DrawImage(graphics, image, this.ImageRectangle, DesignerContentAlignment.Fill);
ActivityDesignerPaint.DrawText(graphics, font, this.Text, TextRectangle, StringAlignment.Near, ambientTheme.TextQuality, designerTheme.ForegroundBrush);
}
#endregion Methods
}
#endregion DesignerLayoutBase class
#region DesignerLayout class
internal class DesignerLayout : DesignerLayoutBase
{
public DesignerLayout(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
}
public override HitTestInfo HitTest(Point point)
{
HitTestInfo hitInfo = HitTestInfo.Nowhere;
if (this.Bounds.Contains(point))
{
hitInfo = new HitTestInfo(this.ActivityDesigner, HitTestLocations.Designer | HitTestLocations.ActionArea);
}
return hitInfo;
}
public virtual Point LeftConnectionPoint
{
get
{
Rectangle layoutBounds = this.Bounds;
int midVert = layoutBounds.Y + (layoutBounds.Height / 2);
Point point = new Point(layoutBounds.Left - 4, midVert);
return point;
}
}
public virtual Point RightConnectionPoint
{
get
{
Rectangle layoutBounds = this.Bounds;
int midVert = layoutBounds.Y + (layoutBounds.Height / 2);
Point point = new Point(layoutBounds.Right + 4, midVert);
return point;
}
}
}
#endregion DesignerLayout class
#region DesignerLinkLayout class
private class DesignerLinkLayout : DesignerLayoutBase
{
#region Fields
private Cursor _previousCursor;
private bool _mouseOver;
private StateDesigner _parentStateDesigner;
#endregion Fields
#region Constructor
public DesignerLinkLayout(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
}
#endregion Constructor
#region Properties
public bool MouseOver
{
get
{
return _mouseOver;
}
set
{
if (value == _mouseOver)
return;
_mouseOver = value;
Invalidate();
}
}
public StateDesigner ParentStateDesigner
{
get
{
return _parentStateDesigner;
}
set
{
_parentStateDesigner = value;
}
}
#endregion Properties
#region Methods
public override void OnMouseEnter()
{
base.OnMouseEnter();
if (this.ParentStateDesigner != null)
{
_previousCursor = this.ParentStateDesigner.Cursor;
this.ParentStateDesigner.Cursor = Cursors.Hand;
}
this.MouseOver = true;
}
public override void OnMouseLeave()
{
base.OnMouseLeave();
if (this.ParentStateDesigner != null)
{
this.ParentStateDesigner.Cursor = _previousCursor;
}
this.MouseOver = false;
Invalidate();
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
ActivityDesigner activityDesigner = this.ActivityDesigner;
if (this.MouseOver)
{
using (Font font = new Font(designerTheme.Font, FontStyle.Underline | designerTheme.Font.Style))
{
Image image = StateDesigner.GetDesignerImage(activityDesigner);
if (image != null)
ActivityDesignerPaint.DrawImage(graphics, image, this.ImageRectangle, DesignerContentAlignment.Fill);
ActivityDesignerPaint.DrawText(graphics, font, this.Text, TextRectangle, StringAlignment.Near, ambientTheme.TextQuality, designerTheme.ForegroundBrush);
}
}
else
base.OnPaint(graphics, designerTheme, ambientTheme);
}
#endregion Methods
}
#endregion DesignerLinkLayout class
#region EventHandlersLayout class
private class EventHandlersLayout : Layout
{
#region Fields
internal const int EventDrivenPadding = 8;
#endregion Fields
#region Constructor
public EventHandlersLayout(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
}
#endregion Constructor
#region Methods
public override void ResizeLayout(Size newSize)
{
base.ResizeLayout(newSize);
int maxEventDrivenWidth = newSize.Width - (EventDrivenPadding * 2);
foreach (Layout layout in this.Layouts)
{
Size size = layout.Size;
if (size.Width > maxEventDrivenWidth)
{
layout.ResizeLayout(new Size(maxEventDrivenWidth, size.Height));
}
}
}
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
Size selectionSize = ambientTheme.SelectionSize;
Size minimumSize = new Size();
foreach (Layout layout in Layouts)
{
layout.OnLayoutSize(graphics, designerTheme, ambientTheme, minimumSize);
minimumSize.Height += layout.Size.Height;
minimumSize.Height += selectionSize.Height;
int layoutWidth = layout.Size.Width + 2 * (selectionSize.Width + ambientTheme.Margin.Width);
minimumSize.Width = Math.Max(minimumSize.Width, layoutWidth);
}
if (this.Layouts.Count > 0)
minimumSize.Height += EventDrivenPadding;
this.MinimumSize = minimumSize;
Size size = new Size();
size.Width = Math.Max(containerSize.Width, minimumSize.Height);
size.Height = minimumSize.Height;
this.Size = size;
}
public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
Size selectionSize = ambientTheme.SelectionSize;
int x = Location.X + EventDrivenPadding;
int y = Location.Y + EventDrivenPadding;
foreach (Layout layout in this.Layouts)
{
layout.Location = new Point(x, y);
DesignerLayoutBase designerLayout = layout as DesignerLayoutBase;
if (designerLayout != null)
designerLayout.ActivityDesigner.Location = layout.Location;
layout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
y += layout.Size.Height + selectionSize.Height;
}
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
base.OnPaint(graphics, designerTheme, ambientTheme);
StateDesigner stateDesigner = (StateDesigner)this.ActivityDesigner;
ContainedDesignersParser parser = stateDesigner._designersParser;
// we only draw the separation line
// if we have at least one event driven and one state
if ((parser.EventDrivenDesigners.Count > 0 || parser.StateInitializationDesigners.Count > 0 || parser.StateFinalizationDesigners.Count > 0) &&
(parser.StateDesigners.Count > 0 || parser.LeafStateDesigners.Count > 0))
{
Rectangle bounds = this.Bounds;
graphics.DrawLine(designerTheme.BorderPen, bounds.Left, bounds.Bottom, bounds.Right, bounds.Bottom);
}
}
#endregion
}
#endregion
#region BreadCrumbBarLayout class
private class BreadCrumbBarLayout : Layout
{
#region Fields
private const string BreadCrumbSeparator = " : ";
private Size _breadCrumbSeparatorSize;
#endregion Fields
#region Constructor
public BreadCrumbBarLayout(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
}
#endregion Constructor
#region Methods
private void InitializeLayouts()
{
this.Layouts.Clear();
StateDesigner rootStateDesigner = (StateDesigner)this.ActivityDesigner;
StateDesigner currentDesigner = rootStateDesigner;
while (currentDesigner != null)
{
DesignerLinkLayout layout = currentDesigner.InlineLayout;
layout.ParentStateDesigner = rootStateDesigner;
this.Layouts.Add(currentDesigner.InlineLayout);
currentDesigner = currentDesigner.ActiveDesigner as StateDesigner;
}
}
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
InitializeLayouts();
CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
if (compositeDesignerTheme == null)
return;
Font font = designerTheme.BoldFont;
_breadCrumbSeparatorSize = StateMachineDesignerPaint.MeasureString(graphics, font, BreadCrumbSeparator, StringAlignment.Near, Size.Empty);
Size size = Size.Empty;
foreach (Layout layout in Layouts)
{
layout.OnLayoutSize(graphics, compositeDesignerTheme, ambientTheme, size);
size.Width += layout.Size.Width + _breadCrumbSeparatorSize.Width;
size.Height = Math.Max(size.Height, layout.Size.Height);
}
this.MinimumSize = size;
this.Size = size;
}
public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
Point location = this.Location;
foreach (Layout layout in this.Layouts)
{
layout.Location = location;
layout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
location.X += layout.Size.Width + _breadCrumbSeparatorSize.Width;
}
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
if (Layouts.Count == 0)
return;
Font font = designerTheme.BoldFont;
TextQuality textQuality = ambientTheme.TextQuality;
Brush brush = designerTheme.ForegroundBrush;
List<Layout> layouts = this.Layouts;
Layout layout;
for (int i = 0; i < layouts.Count - 1; i++)
{
layout = layouts[i];
layout.OnPaint(graphics, designerTheme, ambientTheme);
Rectangle separatorRectangle = new Rectangle(
layout.Bounds.Right,
layout.Location.Y,
_breadCrumbSeparatorSize.Width,
_breadCrumbSeparatorSize.Height);
ActivityDesignerPaint.DrawText(graphics, font, BreadCrumbSeparator, separatorRectangle,
StringAlignment.Near, textQuality, brush);
}
// draw the last one
layout = layouts[layouts.Count - 1];
layout.OnPaint(graphics, designerTheme, ambientTheme);
}
#endregion Methods
}
#endregion
#region TextLayout class
private class TextLayout : Layout
{
#region Constructor
public TextLayout(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
}
#endregion Constructor
#region Methods
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
string text = this.ActivityDesigner.Text;
Size size = Size.Empty;
if (compositeDesignerTheme != null && !String.IsNullOrEmpty(text))
{
size = StateMachineDesignerPaint.MeasureString(graphics, compositeDesignerTheme.Font, text, StringAlignment.Center, Size.Empty);
}
this.MinimumSize = size;
this.Size = size;
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
string text = this.ActivityDesigner.Text;
if (String.IsNullOrEmpty(text))
return;
Font font = designerTheme.Font;
ActivityDesignerPaint.DrawText(graphics, font, text, this.Bounds, StringAlignment.Near, ambientTheme.TextQuality, designerTheme.ForegroundBrush);
}
#endregion Methods
}
#endregion
#region ImageLayout class
private class ImageLayout : Layout
{
#region Constructor
public ImageLayout(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
}
#endregion Constructor
#region Methods
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
Size size = Size.Empty;
if (this.ActivityDesigner.Image != null && compositeDesignerTheme != null)
{
size = designerTheme.ImageSize;
}
this.MinimumSize = size;
this.Size = size;
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
Image image = this.ActivityDesigner.Image;
if (image != null)
ActivityDesignerPaint.DrawImage(graphics, image, this.Bounds, DesignerContentAlignment.Fill);
}
#endregion Methods
}
#endregion
#region TitleBarLayout class
private class TitleBarLayout : Layout
{
#region Fields
private TextLayout _textLayout;
private ImageLayout _imageLayout;
private const int Padding = 4;
#endregion Fields
#region Constructor
public TitleBarLayout(ActivityDesigner activityDesigner)
: base(activityDesigner)
{
_textLayout = new TextLayout(activityDesigner);
this.Layouts.Add(_textLayout);
_imageLayout = new ImageLayout(activityDesigner);
this.Layouts.Add(_imageLayout);
}
#endregion Constructor
#region Properties
public TextLayout TextLayout
{
get
{
return _textLayout;
}
}
public ImageLayout ImageLayout
{
get
{
return _imageLayout;
}
}
#endregion Properties
#region Methods
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
Size minimumSize = new Size();
_textLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, Size.Empty);
_imageLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, Size.Empty);
minimumSize.Width = designerTheme.BorderWidth * 2 + 10 + _textLayout.Size.Width + _imageLayout.Size.Width;
minimumSize.Height = Math.Max(_textLayout.Size.Height, _imageLayout.Size.Height);
minimumSize.Height += designerTheme.BorderWidth * 2 + 4;
this.MinimumSize = minimumSize;
Size size = minimumSize;
size.Width = Math.Max(minimumSize.Width, containerSize.Width);
this.Size = size;
}
public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
Size margin = WorkflowTheme.CurrentTheme.AmbientTheme.Margin;
Point origin = this.Location;
origin.X += margin.Width;
origin.Y += 2;
_imageLayout.Location = origin;
CalculateTextLayout();
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
Rectangle rectangle = this.Bounds;
Brush backgroundBrush = designerTheme.GetBackgroundBrush(this.Bounds);
graphics.FillRectangle(backgroundBrush, rectangle);
Color color1;
Color color2;
StateActivity state = (StateActivity)this.ActivityDesigner.Activity;
if (StateMachineHelpers.IsLeafState(state))
{
color1 = Color.FromArgb(32, designerTheme.BorderColor);
color2 = Color.FromArgb(160, designerTheme.BorderColor);
}
else
{
if (StateMachineHelpers.IsRootState(state))
{
color1 = Color.Empty;
color2 = Color.FromArgb(128, designerTheme.BorderColor);
}
else
{
color1 = Color.FromArgb(16, designerTheme.BorderColor);
color2 = Color.FromArgb(16, designerTheme.BorderColor);
}
}
if (rectangle.Width > 0 && rectangle.Height > 0)
{
using (Brush linearGradientBrush = new LinearGradientBrush(rectangle, color1, color2, LinearGradientMode.Vertical))
{
graphics.FillRectangle(linearGradientBrush, rectangle);
graphics.DrawLine(designerTheme.BorderPen, rectangle.Left, rectangle.Bottom, rectangle.Right, rectangle.Bottom);
}
}
base.OnPaint(graphics, designerTheme, ambientTheme);
}
public override void ResizeLayout(Size newSize)
{
base.ResizeLayout(newSize);
CalculateTextLayout();
}
private void CalculateTextLayout()
{
Size margin = WorkflowTheme.CurrentTheme.AmbientTheme.Margin;
int minX = _imageLayout.Bounds.Right + Padding;
int maxStringWidth = _textLayout.Size.Width;
int xPos = (this.Location.X + this.Size.Width / 2 - maxStringWidth / 2);
if (xPos < minX)
xPos = minX;
if ((xPos + maxStringWidth) > (this.Bounds.Right - margin.Width))
maxStringWidth = (this.Bounds.Right - margin.Width) - xPos;
_textLayout.Location = new Point(xPos, this.Location.Y + margin.Height);
_textLayout.Size = new Size(maxStringWidth, _textLayout.Size.Height);
}
#endregion Methods
}
#endregion
#region StatesLayout class
private class StatesLayout : Layout
{
#region Fields
private const int StatePadding = 16;
private static readonly Size RealMinimumSize = new Size(160, 80);
private TitleBarLayout _titleBarLayout;
private EventHandlersLayout _eventHandlersLayout;
#endregion Fields
#region Constructor
public StatesLayout(
ActivityDesigner activityDesigner,
TitleBarLayout titleBarLayout,
EventHandlersLayout eventHandlersLayout)
: base(activityDesigner)
{
_titleBarLayout = titleBarLayout;
this.Layouts.Add(titleBarLayout);
_eventHandlersLayout = eventHandlersLayout;
this.Layouts.Add(eventHandlersLayout);
}
#endregion Constructor
#region Properties
private StateDesigner StateDesigner
{
get
{
return (StateDesigner)this.ActivityDesigner;
}
}
public override Size MinimumSize
{
get
{
Size minimumSize = base.MinimumSize;
minimumSize.Width = Math.Max(minimumSize.Width, RealMinimumSize.Width);
minimumSize.Height = Math.Max(minimumSize.Height, RealMinimumSize.Height);
return minimumSize;
}
}
public EventHandlersLayout EventHandlersLayout
{
get
{
return _eventHandlersLayout;
}
}
#endregion Properties
#region Methods
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
CompositeDesignerTheme compositeDesignerTheme = (CompositeDesignerTheme)designerTheme;
Size size = containerSize;
_titleBarLayout.OnLayoutSize(graphics, compositeDesignerTheme, ambientTheme, size);
_eventHandlersLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
int minWidth = Math.Max(_titleBarLayout.MinimumSize.Width, _eventHandlersLayout.MinimumSize.Width);
int minHeight = _titleBarLayout.MinimumSize.Height + _eventHandlersLayout.MinimumSize.Height;
this.MinimumSize = new Size(minWidth, minHeight);
size.Width = Math.Max(minWidth, size.Width);
size.Height = Math.Max(minHeight, size.Height);
if (this.StateDesigner.NeedsAutoLayout)
{
int maximumX = size.Width;
int maximumY = _titleBarLayout.Size.Height +
_eventHandlersLayout.Size.Height +
DefaultStateDesignerAutoLayoutDistance;
bool containsStates = false;
foreach (ActivityDesigner designer in this.StateDesigner.ContainedDesigners)
{
if (!this.StateDesigner.IsContainedDesignerVisible(designer))
continue;
StateDesigner stateDesigner = designer as StateDesigner;
if (stateDesigner == null)
continue;
containsStates = true;
maximumX = Math.Max(maximumX, designer.Size.Width);
maximumY += designer.Size.Height + DefaultStateDesignerAutoLayoutDistance;
}
if (containsStates)
{
// Add some extra padding to take into account for the AutoSize growth
maximumY += DefaultStateDesignerAutoLayoutDistance * 2;
}
size = new Size(maximumX, maximumY);
}
_titleBarLayout.ResizeLayout(new Size(size.Width, _titleBarLayout.Size.Height));
this.Size = size;
}
public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
_titleBarLayout.Location = this.Location;
_titleBarLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
int x = this.Location.X;
int y = _titleBarLayout.Bounds.Bottom + 1;
_eventHandlersLayout.Location = new Point(x, y);
_eventHandlersLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
GraphicsPath path = StateMachineDesignerPaint.GetDesignerPath(this.ActivityDesigner, this.Bounds, designerTheme);
Brush backgroundBrush = designerTheme.GetBackgroundBrush(this.Bounds);
graphics.FillPath(backgroundBrush, path);
base.OnPaint(graphics, designerTheme, ambientTheme);
if (ambientTheme.ShowDesignerBorder)
graphics.DrawPath(designerTheme.BorderPen, path);
if (this.StateDesigner.ContainedDesigners.Count == 0 &&
!this.StateDesigner.IsStateCustomActivity)
{
Point location = new Point(this.Location.X, _titleBarLayout.Bounds.Bottom);
Size size = new Size(this.Size.Width, this.Size.Height - _titleBarLayout.Bounds.Height);
Rectangle rectangle = new Rectangle(location, size);
rectangle.Inflate(-1, -1);
StateActivity state = (StateActivity)this.StateDesigner.Activity;
if (StateMachineHelpers.IsLeafState(state) &&
StateMachineHelpers.IsCompletedState(state))
return;
if (this.StateDesigner.DragDropActive)
{
Color color = Color.FromArgb(64, designerTheme.ForeColor);
using (SolidBrush brush = new SolidBrush(color))
{
ActivityDesignerPaint.DrawText(
graphics,
designerTheme.Font,
this.StateDesigner.HelpText,
rectangle,
StringAlignment.Center,
ambientTheme.TextQuality,
brush);
}
}
else
{
ActivityDesignerPaint.DrawText(
graphics,
designerTheme.Font,
this.StateDesigner.HelpText,
rectangle,
StringAlignment.Center,
ambientTheme.TextQuality,
designerTheme.ForegroundBrush);
}
}
}
public override void ResizeLayout(Size newSize)
{
_eventHandlersLayout.ResizeLayout(new Size(newSize.Width, _eventHandlersLayout.Size.Height));
_titleBarLayout.ResizeLayout(new Size(newSize.Width, _titleBarLayout.Size.Height));
base.ResizeLayout(newSize);
}
#endregion Methods
}
#endregion StatesLayout class
#region EventDrivenLayout class
private class EventDrivenLayout : Layout
{
#region Fields
private BreadCrumbBarLayout _breadCrumbBarLayout;
private TitleBarLayout _titleBarLayout;
private DesignerLinkLayout _designerLayout;
private const int ActiveDesignerPadding = 16;
#endregion
#region Constructor
public EventDrivenLayout(ActivityDesigner activityDesigner, TitleBarLayout titleBarLayout)
: base(activityDesigner)
{
_breadCrumbBarLayout = new BreadCrumbBarLayout(activityDesigner);
_designerLayout = new DesignerLinkLayout(activityDesigner);
StateDesigner stateDesigner = activityDesigner as StateDesigner;
if (stateDesigner != null)
{
_designerLayout.ParentStateDesigner = stateDesigner;
_designerLayout.MouseDown += new MouseEventHandler(stateDesigner.StateDesignerLinkMouseDown);
}
_titleBarLayout = titleBarLayout;
}
private void InitializeLayout()
{
this.Layouts.Clear();
if (this.StateDesigner.IsRootStateDesigner)
{
// we only display the title bar and
// the bread crumb bar at the top most level
this.Layouts.Add(_titleBarLayout);
this.Layouts.Add(_breadCrumbBarLayout);
}
else
{
this.Layouts.Add(_designerLayout);
}
}
#endregion
#region Properties
private StateDesigner StateDesigner
{
get
{
return (StateDesigner)this.ActivityDesigner;
}
}
#endregion Properties
#region Methods
public override void OnLayoutSize(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme, Size containerSize)
{
base.OnLayoutSize(graphics, designerTheme, ambientTheme, containerSize);
InitializeLayout();
Size size = containerSize;
Size minSize = this.StateDesigner.MinimumSize;
size.Width = Math.Max(size.Width, minSize.Width);
size.Height = Math.Max(size.Height, minSize.Height);
ActivityDesigner activeDesigner = this.StateDesigner.ActiveDesigner;
Size activeDesignerSize = activeDesigner.Size;
if (this.StateDesigner.IsRootStateDesigner)
{
_titleBarLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
_breadCrumbBarLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
size.Width = Math.Max(size.Width, activeDesignerSize.Width + ActiveDesignerPadding * 2);
size.Width = Math.Max(size.Width, _titleBarLayout.Size.Width);
size.Width = Math.Max(size.Width, _breadCrumbBarLayout.Size.Width);
int minHeight =
activeDesignerSize.Height +
_titleBarLayout.Size.Height +
_breadCrumbBarLayout.Size.Height +
ActiveDesignerPadding * 3 +
ambientTheme.SelectionSize.Height * 2;
size.Height = Math.Max(size.Height, minHeight);
_titleBarLayout.ResizeLayout(new Size(size.Width, _titleBarLayout.Size.Height));
}
else
{
_designerLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, size);
size.Width = Math.Max(size.Width, activeDesigner.Size.Width + ActiveDesignerPadding * 2);
size.Width = Math.Max(size.Width, _designerLayout.Size.Width);
size.Height = Math.Max(size.Height, activeDesigner.Size.Height + ActiveDesignerPadding * 2 + _designerLayout.Size.Height + ambientTheme.SelectionSize.Height * 2);
}
this.MinimumSize = size;
this.Size = size;
}
public override void OnLayoutPosition(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
CompositeDesignerTheme compositeDesignerTheme = designerTheme as CompositeDesignerTheme;
if (compositeDesignerTheme == null)
return;
Rectangle bounds = this.Bounds;
Point origin = bounds.Location;
if (this.StateDesigner.IsRootStateDesigner)
{
_titleBarLayout.Location = origin;
_titleBarLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
origin.X += ActiveDesignerPadding;
origin.Y += _titleBarLayout.Size.Height + ActiveDesignerPadding;
_breadCrumbBarLayout.Location = origin;
_breadCrumbBarLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
origin.Y += _breadCrumbBarLayout.Size.Height + ActiveDesignerPadding;
}
else
{
Point designerLayoutLocation = new Point(
bounds.Left + (bounds.Width - _designerLayout.Size.Width) / 2,
bounds.Top + ambientTheme.SelectionSize.Height);
_designerLayout.Location = designerLayoutLocation;
_designerLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
origin.Y = _designerLayout.Bounds.Bottom + ambientTheme.SelectionSize.Height + ActiveDesignerPadding;
}
Size activeDesignerSize = this.StateDesigner.ActiveDesigner.Size;
origin.X = bounds.Left + (bounds.Width - activeDesignerSize.Width) / 2;
this.StateDesigner.ActiveDesigner.Location = origin;
}
public override void OnPaint(Graphics graphics, ActivityDesignerTheme designerTheme, AmbientTheme ambientTheme)
{
GraphicsPath path = StateMachineDesignerPaint.GetDesignerPath(this.ActivityDesigner, this.Bounds, designerTheme);
Brush backgroundBrush = designerTheme.GetBackgroundBrush(this.Bounds);
graphics.FillPath(backgroundBrush, path);
base.OnPaint(graphics, designerTheme, ambientTheme);
if (ambientTheme.ShowDesignerBorder)
graphics.DrawPath(designerTheme.BorderPen, path);
}
public override void ResizeLayout(Size newSize)
{
if (this.StateDesigner.IsRootStateDesigner)
{
_titleBarLayout.ResizeLayout(new Size(newSize.Width, _titleBarLayout.Size.Height));
}
base.ResizeLayout(newSize);
}
#endregion Methods
}
#endregion
}
}
|