DynamicActionMessageFilter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Design / MessageFilters / DynamicActionMessageFilter.cs / 1305376 / DynamicActionMessageFilter.cs

                            namespace System.Workflow.ComponentModel.Design 
{
 	using System;
	using System.Text;
	using System.Drawing; 
	using System.Windows.Forms;
 	using System.Drawing.Drawing2D; 
	using System.Collections.Generic; 
 	using System.ComponentModel.Design;
 
 	#region Class DynamicActionMessageFilter
	//Behavior needs coordinates in client coordinate system
 	internal sealed class DynamicActionMessageFilter : WorkflowDesignerMessageFilter
	{ 
		#region Members, Construction and Destruction
		private List actions = new List(); 
 
 		private int draggedButtonIndex = -1;
		private int draggedActionIndex = -1; 
 		
 		private bool infoTipSet = false;

		internal DynamicActionMessageFilter() 
        {
 		} 
		#endregion 

		#region Properties and Methods 
		internal void AddAction(DynamicAction action)
 		{
			if (action == null)
 				throw new ArgumentNullException("action"); 

 			if (!this.actions.Contains(action)) 
			{ 
 				if (IsButtonDragged)
					SetDraggedButton(-1, -1); 

				this.actions.Add(action);
				RefreshAction(action);
 			} 
		}
 
 		internal bool ActionExists(DynamicAction action) 
 		{
			if (action == null) 
 				throw new ArgumentNullException("action");

			return this.actions.Contains(action);
		} 

		internal void RemoveAction(DynamicAction action) 
 		{ 
			if (action == null)
 				throw new ArgumentNullException("action"); 

 			if (this.actions.Contains(action))
			{
 				if (IsButtonDragged) 
					SetDraggedButton(-1, -1);
 
				RefreshAction(action); 
				this.actions.Remove(action);
 			} 
		}

 		internal void RefreshAction(DynamicAction action)
 		{ 
			if (action == null)
 				throw new ArgumentNullException("action"); 
 
			int actionIndex = this.actions.IndexOf(action);
			if (actionIndex >= 0) 
				ParentView.InvalidateClientRectangle(GetActionBounds(actionIndex));
 		}
		#endregion
 
 		#region Behavior Overrides
 		protected override void Initialize(WorkflowView parentView) 
		{ 
 			base.Initialize(parentView);
 
			IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer;
			if (serviceContainer != null)
			{
 				serviceContainer.RemoveService(typeof(DynamicActionMessageFilter)); 
				serviceContainer.AddService(typeof(DynamicActionMessageFilter), this);
 			} 
 		} 

		protected override void Dispose(bool disposing) 
 		{
			try
			{
				IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer; 
 				if (serviceContainer != null)
					serviceContainer.RemoveService(typeof(DynamicActionMessageFilter)); 
 			} 
 			finally
			{ 
 				base.Dispose(disposing);
			}
		}
 
		protected override bool OnMouseEnter(MouseEventArgs eventArgs)
 		{ 
			UpdateTransparency(new Point(eventArgs.X, eventArgs.Y)); 
 			Refresh();
 			return false; 
		}

 		protected override bool OnMouseDown(MouseEventArgs eventArgs)
		{ 
			Point clientPoint = new Point(eventArgs.X, eventArgs.Y);
 
			Refresh(); 
 			UpdateTransparency(clientPoint);
 
			bool retval = false;
 			if ((eventArgs.Button & MouseButtons.Left) > 0)
 			{
				for (int i = this.actions.Count - 1; i >= 0; i--) 
 				{
					DynamicAction action = this.actions[i]; 
					Rectangle actionBounds = GetActionBounds(i); 
					if (actionBounds.Contains(clientPoint))
 					{ 
						//If we clicked on disabled button then no further action is needed
 						for (int j = 0; j < action.Buttons.Count; j++)
 						{
							Rectangle buttonBounds = GetButtonBounds(i, j); 
 							if (buttonBounds.Contains(clientPoint) && action.Buttons[j].State == ActionButton.States.Disabled)
								return true; 
						} 

						//Now check all the buttons and update their states 
 						for (int j = 0; j < action.Buttons.Count; j++)
						{
 							ActionButton actionButton = action.Buttons[j];
 							if (actionButton.State != ActionButton.States.Disabled) 
							{
 								Rectangle buttonBounds = GetButtonBounds(i, j); 
								if (buttonBounds.Contains(clientPoint)) 
								{
									actionButton.State = ActionButton.States.Pressed; 
 									if (action.ActionType != DynamicAction.ActionTypes.TwoState)
										SetDraggedButton(i, j);
 								}
 								else if (action.ActionType == DynamicAction.ActionTypes.TwoState) 
								{
 									actionButton.State = ActionButton.States.Normal; 
								} 
							}
						} 

 						retval = true;
					}
 				} 
 			}
 
			return retval; 
 		}
 
		protected override bool OnMouseMove(MouseEventArgs eventArgs)
		{
			Point clientPoint = new Point(eventArgs.X, eventArgs.Y);
 
 			Refresh();
			UpdateTransparency(clientPoint); 
 
 			string infoTip = String.Empty;
 			bool retval = IsButtonDragged; 
			if (!IsButtonDragged)
 			{
				for (int i = this.actions.Count - 1; i >= 0; i--)
				{ 
					DynamicAction action = this.actions[i];
 					Rectangle actionBounds = GetActionBounds(i); 
 
					for (int j = 0; j < action.Buttons.Count; j++)
 					{ 
 						ActionButton actionButton = action.Buttons[j];

						if (actionBounds.Contains(clientPoint))
 						{ 
							Rectangle buttonBounds = GetButtonBounds(i, j);
							bool buttonContainsPoint = buttonBounds.Contains(clientPoint); 
 
							if (buttonContainsPoint && infoTip.Length == 0)
 								infoTip = actionButton.Description; 

							if (actionButton.State != ActionButton.States.Disabled &&
 								actionButton.State != ActionButton.States.Pressed)
 							{ 
								if (buttonContainsPoint)
 									actionButton.State = ActionButton.States.Highlight; 
								else 
									actionButton.State = ActionButton.States.Normal;
							} 

 							retval = true;
						}
 						else 
 						{
							if (actionButton.State == ActionButton.States.Highlight) 
 								actionButton.State = ActionButton.States.Normal; 
						}
					} 
				}
 			}

			WorkflowView parentView = ParentView; 
 			if (infoTip.Length > 0)
 			{ 
				this.infoTipSet = true; 
 				parentView.ShowInfoTip(infoTip);
			} 
			else if (this.infoTipSet)
			{
 				parentView.ShowInfoTip(String.Empty);
				this.infoTipSet = false; 
 			}
 
 			return retval; 
		}
 
 		protected override bool OnMouseDoubleClick(MouseEventArgs eventArgs)
		{
			for (int i = this.actions.Count - 1; i >= 0; i--)
			{ 
 				DynamicAction action = this.actions[i];
				Rectangle actionBounds = GetActionBounds(i); 
 				if (actionBounds.Contains(new Point(eventArgs.X, eventArgs.Y))) 
 					return true;
			} 

 			return false;
		}
 
		protected override bool OnMouseUp(MouseEventArgs eventArgs)
		{ 
 			Point clientPoint = new Point(eventArgs.X, eventArgs.Y); 

			Refresh(); 
 			UpdateTransparency(clientPoint);

 			bool retval = false;
			if ((eventArgs.Button & MouseButtons.Left) > 0) 
 			{
				for (int i = this.actions.Count - 1; i >= 0; i--) 
				{ 
					DynamicAction action = this.actions[i];
 					Rectangle actionBounds = GetActionBounds(i); 
					if (actionBounds.Contains(clientPoint))
 					{
 						for (int j = 0; j < action.Buttons.Count; j++)
						{ 
 							ActionButton actionButton = action.Buttons[j];
 
							if (actionButton.State != ActionButton.States.Disabled) 
							{
								Rectangle buttonBounds = GetButtonBounds(i, j); 

 								if (buttonBounds.Contains(clientPoint) && action.ActionType != DynamicAction.ActionTypes.TwoState)
									actionButton.State = ActionButton.States.Highlight;
 								else if (actionButton.State == ActionButton.States.Highlight) 
 									actionButton.State = ActionButton.States.Normal;
							} 
 						} 

						retval = true; 
					}
				}
 			}
 
			if (IsButtonDragged)
 				SetDraggedButton(-1, -1); 
 
 			return retval;
		} 

 		protected override bool OnMouseLeave()
		{
			ParentView.ShowInfoTip(String.Empty); 
			UpdateTransparency(Point.Empty);
 			Refresh(); 
			return false; 
 		}
 
 		protected override bool OnMouseCaptureChanged()
		{
 			if (IsButtonDragged)
				SetDraggedButton(-1, -1); 
			return false;
		} 
 
 		protected override bool OnPaintWorkflowAdornments(PaintEventArgs e, Rectangle viewPort, AmbientTheme ambientTheme)
        { 
			for (int i = 0; i < this.actions.Count; i++)
 			{
 				GraphicsContainer graphicsState = e.Graphics.BeginContainer();
				Point actionLocation = GetActionBounds(i).Location; 
 				e.Graphics.TranslateTransform(actionLocation.X, actionLocation.Y);
				this.actions[i].Draw(e.Graphics); 
				e.Graphics.EndContainer(graphicsState); 
			}
 			return false; 
		}
 		#endregion

 		#region Helpers 
		private void Refresh()
 		{ 
			WorkflowView parentView = ParentView; 
			for (int i = 0; i < this.actions.Count; i++)
				parentView.InvalidateClientRectangle(GetActionBounds(i)); 
 		}

		private Rectangle GetActionBounds(int actionIndex)
 		{ 
 			Rectangle bounds = new Rectangle(Point.Empty, ParentView.ViewPortSize);
			DynamicAction action = this.actions[actionIndex]; 
 
 			bounds.Inflate(-action.DockMargin.Width, -action.DockMargin.Height);
            return new Rectangle(ActivityDesignerPaint.GetRectangleFromAlignment(action.Doc----gnment, bounds, action.Bounds.Size).Location, action.Bounds.Size); 
        }

		private Rectangle GetButtonBounds(int actionIndex, int buttonIndex)
		{ 
			Rectangle bounds = GetActionBounds(actionIndex);
 			Rectangle buttonBounds = this.actions[actionIndex].GetButtonBounds(buttonIndex); 
			buttonBounds.Offset(bounds.Location); 
 			return buttonBounds;
 		} 

		private void UpdateTransparency(Point point)
 		{
			for (int i = 0; i < this.actions.Count; i++) 
			{
				float transparency = 0; 
 				if (!point.IsEmpty) 
				{
 					Rectangle actionBounds = GetActionBounds(i); 
 					if (actionBounds.Contains(point) || this.draggedActionIndex == i)
					{
 						transparency = 1.0f;
					} 
					else
					{ 
 						Rectangle rectangle = ParentView.ViewPortRectangle; 
						double distance = DesignerGeometryHelper.DistanceFromPointToRectangle(point, actionBounds);
 						if (distance > rectangle.Width / 3 || distance > rectangle.Height / 3) 
 						{
							transparency = 0.3f;
 						}
						else 
						{
							//Uncomment the following code for fluctuating transparency 
 							//1.0f - ((float)Convert.ToInt32(distance)) / Math.Max(ParentView.ViewPortSize.Width, ParentView.ViewPortSize.Height); 
							transparency = 1.0f;
 						} 
 					}
				}

 				this.actions[i].Transparency = transparency; 
			}
		} 
 
		private bool IsButtonDragged
 		{ 
			get
 			{
 				return (this.draggedActionIndex >= 0 && this.draggedButtonIndex >= 0);
			} 
 		}
 
		private void SetDraggedButton(int actionIndex, int buttonIndex) 
		{
			if (this.draggedActionIndex == actionIndex && this.draggedButtonIndex == buttonIndex) 
 				return;

			WorkflowView parentView = ParentView;
 			if (this.draggedActionIndex >= 0 && this.draggedButtonIndex >= 0) 
 			{
				if (this.draggedActionIndex < this.actions.Count) 
 					this.actions[this.draggedActionIndex].Buttons[this.draggedButtonIndex].State = ActionButton.States.Highlight; 

				this.draggedActionIndex = -1; 
				this.draggedButtonIndex = -1;
				parentView.Capture = false;
 				UpdateTransparency(parentView.PointToClient(Control.MousePosition));
			} 

 			this.draggedActionIndex = actionIndex; 
 			this.draggedButtonIndex = buttonIndex; 

			if (this.draggedActionIndex >= 0 && this.draggedButtonIndex >= 0) 
 				parentView.Capture = true;
		}
		#endregion
	} 
 	#endregion
 
	#region Class DynamicAction 
 	internal class DynamicAction : IDisposable
 	{ 
		#region Members and constructor
 		private static float DefaultTransparency = 0.0f;
		private static Size[] Sizes = new Size[] { new Size(20, 20), new Size(24, 24), new Size(28, 28), new Size(32, 32), new Size(36, 36) };
		private static Size[] Margins = new Size[] { new Size(1, 1), new Size(1, 1), new Size(2, 2), new Size(2, 2), new Size(3, 3) }; 
		internal enum ButtonSizes { Small = 0, SmallMedium = 1, Medium = 2, MediumLarge = 3, Large = 4 };
 		internal enum ActionTypes { Standard = 1, TwoState = 2 }; 
 
		private ItemList buttons = null;
 		private ButtonSizes buttonSizeType = ButtonSizes.Medium; 
 		private DesignerContentAlignment doc----gnment = DesignerContentAlignment.TopLeft;
		private float minimumTransparency = DynamicAction.DefaultTransparency;
 		private float transparency = DynamicAction.DefaultTransparency;
		private ActionTypes actionType = ActionTypes.Standard; 

		private Size borderSize = new Size(2, 2); 
		private Size dockMargin = DynamicAction.Sizes[(int)ButtonSizes.Medium]; 
 		private Size buttonSize = DynamicAction.Sizes[(int)ButtonSizes.Medium];
		private Size margin = DynamicAction.Margins[(int)ButtonSizes.Medium]; 

 		internal DynamicAction()
 		{
			this.buttons = new ItemList(this); 
 		}
 
        ~DynamicAction() 
        {
            Dispose(false); 
        }

		public void Dispose()
		{ 
            Dispose(true);
            GC.SuppressFinalize(this); 
		} 

        protected virtual void Dispose(bool disposing) 
        {
            foreach (ActionButton button in this.buttons)
                ((IDisposable)button).Dispose();
            this.buttons.Clear(); 
        }
 		#endregion 
 
		#region Properties and Methods
 		internal IList Buttons 
 		{
			get
 			{
				return this.buttons; 
			}
		} 
 
 		internal Size DockMargin
		{ 
 			get
 			{
				return this.dockMargin;
 			} 

			set 
			{ 
				this.dockMargin = value;
 			} 
		}

 		internal ActionTypes ActionType
 		{ 
			get
 			{ 
				return this.actionType; 
			}
		} 

 		internal ButtonSizes ButtonSize
		{
 			get 
 			{
				return this.buttonSizeType; 
 			} 

			set 
			{
				if (this.buttonSizeType == value)
 					return;
 
				this.buttonSizeType = value;
 				this.buttonSize = DynamicAction.Sizes[(int)this.buttonSizeType]; 
 				this.margin = DynamicAction.Margins[(int)this.buttonSizeType]; 
			}
 		} 

		internal DesignerContentAlignment Doc----gnment
		{
			get 
 			{
				return this.doc----gnment; 
 			} 

 			set 
			{
 				if (this.doc----gnment == value)
					return;
 
				this.doc----gnment = value;
			} 
 		} 

		internal float Transparency 
 		{
 			get
			{
 				return this.transparency; 
			}
 
			set 
			{
 				if (this.transparency == value) 
					return;

 				this.transparency = Math.Max(DynamicAction.DefaultTransparency, value);
 			} 
		}
 
 		internal void Draw(Graphics graphics) 
		{
            if (this.transparency == 0 || this.buttons.Count == 0) 
                return;

            ActivityDesignerPaint.Draw3DButton(graphics, null, Bounds, this.transparency - 0.1f, ButtonState.Normal);
 
            for (int i = 0; i < this.buttons.Count; i++)
			{ 
				Rectangle buttonBounds = GetButtonBounds(i); 
 				ActionButton button = this.buttons[i];
				if (button.StateImages.Length == 1) 
 				{
 					Image buttonImage = button.StateImages[0];
					if (button.State == ActionButton.States.Normal || button.State == ActionButton.States.Disabled)
 					{ 
						buttonBounds.Inflate(-2, -2);
						ActivityDesignerPaint.DrawImage(graphics, buttonImage, buttonBounds, new Rectangle(Point.Empty, buttonImage.Size), DesignerContentAlignment.Fill, transparency, (button.State == ActionButton.States.Disabled)); 
                    } 
					else
 					{ 
						ButtonState state = (button.State == ActionButton.States.Highlight) ? ButtonState.Normal : ButtonState.Pushed;
                        ActivityDesignerPaint.Draw3DButton(graphics, buttonImage, buttonBounds, this.transparency, state);
                    }
 				} 
 				else
				{ 
 					Image buttonImage = this.buttons[i].StateImages[(int)this.buttons[i].State]; 
					buttonBounds.Inflate(-2, -2);
					ActivityDesignerPaint.DrawImage(graphics, buttonImage, buttonBounds, new Rectangle(Point.Empty, buttonImage.Size), DesignerContentAlignment.Fill, this.transparency, false); 
                }
			}
 		}
 
		internal Rectangle Bounds
 		{ 
 			get 
			{
 				Size size = Size.Empty; 
				int buttonCount = Math.Max(1, this.buttons.Count);
				size.Width = (2 * borderSize.Width) + (buttonCount * this.buttonSize.Width) + ((buttonCount + 1) * this.margin.Width);
				size.Height = (2 * borderSize.Height) + this.buttonSize.Height + (2 * this.margin.Height);
 				return new Rectangle(Point.Empty, size); 
			}
 		} 
 
 		internal Rectangle GetButtonBounds(int buttonIndex)
		{ 
 			if (buttonIndex < 0 || buttonIndex >= this.buttons.Count)
				throw new ArgumentOutOfRangeException("buttonIndex");

			Rectangle rectangle = Rectangle.Empty; 
			rectangle.X = this.borderSize.Width + (buttonIndex * this.buttonSize.Width) + ((buttonIndex + 1) * this.margin.Width);
 			rectangle.Y = this.borderSize.Height + this.margin.Height; 
			rectangle.Size = this.buttonSize; 
 			return rectangle;
 		} 
		#endregion
 	}
	#endregion
 
	#region Class ActionButton
	internal sealed class ActionButton : IDisposable 
 	{ 
		#region Members, Constructor and Destruction
 		internal enum States { Normal = 0, Highlight = 1, Pressed = 2, Disabled = 3 }; 

 		internal event EventHandler StateChanged;

		private Image[] stateImages = null; 
 		private string description = String.Empty;
		private States buttonState = States.Normal; 
 
		internal ActionButton(Image[] stateImages)
		{ 
 			StateImages = stateImages;
		}

 		void IDisposable.Dispose() 
 		{
		} 
 		#endregion 

		#region Properties and Methods 
		internal Image[] StateImages
		{
 			get
			{ 
 				return this.stateImages;
 			} 
 
			set
 			{ 
				if (value == null)
					throw new ArgumentNullException("value");

			    if (value.Length != 1 && value.Length != 4) 
 					throw new ArgumentException(SR.GetString(SR.Error_InvalidStateImages), "value");
 
				this.stateImages = value; 
 				foreach (Image image in this.stateImages)
 				{ 
					Bitmap bitmap = image as Bitmap;
 					if (bitmap != null)
						bitmap.MakeTransparent(AmbientTheme.TransparentColor);
				} 
			}
 		} 
 
		internal States State
 		{ 
 			get
			{
 				return this.buttonState;
			} 

			set 
			{ 
 				if (this.buttonState == value)
					return; 

 				this.buttonState = value;

 				if (StateChanged != null) 
					StateChanged(this, EventArgs.Empty);
 			} 
		} 

		internal string Description 
		{
 			get
			{
 				return this.description; 
 			}
 
			set 
 			{
				this.description = value; 
			}
		}
 		#endregion
	} 
 	#endregion
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace System.Workflow.ComponentModel.Design 
{
 	using System;
	using System.Text;
	using System.Drawing; 
	using System.Windows.Forms;
 	using System.Drawing.Drawing2D; 
	using System.Collections.Generic; 
 	using System.ComponentModel.Design;
 
 	#region Class DynamicActionMessageFilter
	//Behavior needs coordinates in client coordinate system
 	internal sealed class DynamicActionMessageFilter : WorkflowDesignerMessageFilter
	{ 
		#region Members, Construction and Destruction
		private List actions = new List(); 
 
 		private int draggedButtonIndex = -1;
		private int draggedActionIndex = -1; 
 		
 		private bool infoTipSet = false;

		internal DynamicActionMessageFilter() 
        {
 		} 
		#endregion 

		#region Properties and Methods 
		internal void AddAction(DynamicAction action)
 		{
			if (action == null)
 				throw new ArgumentNullException("action"); 

 			if (!this.actions.Contains(action)) 
			{ 
 				if (IsButtonDragged)
					SetDraggedButton(-1, -1); 

				this.actions.Add(action);
				RefreshAction(action);
 			} 
		}
 
 		internal bool ActionExists(DynamicAction action) 
 		{
			if (action == null) 
 				throw new ArgumentNullException("action");

			return this.actions.Contains(action);
		} 

		internal void RemoveAction(DynamicAction action) 
 		{ 
			if (action == null)
 				throw new ArgumentNullException("action"); 

 			if (this.actions.Contains(action))
			{
 				if (IsButtonDragged) 
					SetDraggedButton(-1, -1);
 
				RefreshAction(action); 
				this.actions.Remove(action);
 			} 
		}

 		internal void RefreshAction(DynamicAction action)
 		{ 
			if (action == null)
 				throw new ArgumentNullException("action"); 
 
			int actionIndex = this.actions.IndexOf(action);
			if (actionIndex >= 0) 
				ParentView.InvalidateClientRectangle(GetActionBounds(actionIndex));
 		}
		#endregion
 
 		#region Behavior Overrides
 		protected override void Initialize(WorkflowView parentView) 
		{ 
 			base.Initialize(parentView);
 
			IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer;
			if (serviceContainer != null)
			{
 				serviceContainer.RemoveService(typeof(DynamicActionMessageFilter)); 
				serviceContainer.AddService(typeof(DynamicActionMessageFilter), this);
 			} 
 		} 

		protected override void Dispose(bool disposing) 
 		{
			try
			{
				IServiceContainer serviceContainer = GetService(typeof(IServiceContainer)) as IServiceContainer; 
 				if (serviceContainer != null)
					serviceContainer.RemoveService(typeof(DynamicActionMessageFilter)); 
 			} 
 			finally
			{ 
 				base.Dispose(disposing);
			}
		}
 
		protected override bool OnMouseEnter(MouseEventArgs eventArgs)
 		{ 
			UpdateTransparency(new Point(eventArgs.X, eventArgs.Y)); 
 			Refresh();
 			return false; 
		}

 		protected override bool OnMouseDown(MouseEventArgs eventArgs)
		{ 
			Point clientPoint = new Point(eventArgs.X, eventArgs.Y);
 
			Refresh(); 
 			UpdateTransparency(clientPoint);
 
			bool retval = false;
 			if ((eventArgs.Button & MouseButtons.Left) > 0)
 			{
				for (int i = this.actions.Count - 1; i >= 0; i--) 
 				{
					DynamicAction action = this.actions[i]; 
					Rectangle actionBounds = GetActionBounds(i); 
					if (actionBounds.Contains(clientPoint))
 					{ 
						//If we clicked on disabled button then no further action is needed
 						for (int j = 0; j < action.Buttons.Count; j++)
 						{
							Rectangle buttonBounds = GetButtonBounds(i, j); 
 							if (buttonBounds.Contains(clientPoint) && action.Buttons[j].State == ActionButton.States.Disabled)
								return true; 
						} 

						//Now check all the buttons and update their states 
 						for (int j = 0; j < action.Buttons.Count; j++)
						{
 							ActionButton actionButton = action.Buttons[j];
 							if (actionButton.State != ActionButton.States.Disabled) 
							{
 								Rectangle buttonBounds = GetButtonBounds(i, j); 
								if (buttonBounds.Contains(clientPoint)) 
								{
									actionButton.State = ActionButton.States.Pressed; 
 									if (action.ActionType != DynamicAction.ActionTypes.TwoState)
										SetDraggedButton(i, j);
 								}
 								else if (action.ActionType == DynamicAction.ActionTypes.TwoState) 
								{
 									actionButton.State = ActionButton.States.Normal; 
								} 
							}
						} 

 						retval = true;
					}
 				} 
 			}
 
			return retval; 
 		}
 
		protected override bool OnMouseMove(MouseEventArgs eventArgs)
		{
			Point clientPoint = new Point(eventArgs.X, eventArgs.Y);
 
 			Refresh();
			UpdateTransparency(clientPoint); 
 
 			string infoTip = String.Empty;
 			bool retval = IsButtonDragged; 
			if (!IsButtonDragged)
 			{
				for (int i = this.actions.Count - 1; i >= 0; i--)
				{ 
					DynamicAction action = this.actions[i];
 					Rectangle actionBounds = GetActionBounds(i); 
 
					for (int j = 0; j < action.Buttons.Count; j++)
 					{ 
 						ActionButton actionButton = action.Buttons[j];

						if (actionBounds.Contains(clientPoint))
 						{ 
							Rectangle buttonBounds = GetButtonBounds(i, j);
							bool buttonContainsPoint = buttonBounds.Contains(clientPoint); 
 
							if (buttonContainsPoint && infoTip.Length == 0)
 								infoTip = actionButton.Description; 

							if (actionButton.State != ActionButton.States.Disabled &&
 								actionButton.State != ActionButton.States.Pressed)
 							{ 
								if (buttonContainsPoint)
 									actionButton.State = ActionButton.States.Highlight; 
								else 
									actionButton.State = ActionButton.States.Normal;
							} 

 							retval = true;
						}
 						else 
 						{
							if (actionButton.State == ActionButton.States.Highlight) 
 								actionButton.State = ActionButton.States.Normal; 
						}
					} 
				}
 			}

			WorkflowView parentView = ParentView; 
 			if (infoTip.Length > 0)
 			{ 
				this.infoTipSet = true; 
 				parentView.ShowInfoTip(infoTip);
			} 
			else if (this.infoTipSet)
			{
 				parentView.ShowInfoTip(String.Empty);
				this.infoTipSet = false; 
 			}
 
 			return retval; 
		}
 
 		protected override bool OnMouseDoubleClick(MouseEventArgs eventArgs)
		{
			for (int i = this.actions.Count - 1; i >= 0; i--)
			{ 
 				DynamicAction action = this.actions[i];
				Rectangle actionBounds = GetActionBounds(i); 
 				if (actionBounds.Contains(new Point(eventArgs.X, eventArgs.Y))) 
 					return true;
			} 

 			return false;
		}
 
		protected override bool OnMouseUp(MouseEventArgs eventArgs)
		{ 
 			Point clientPoint = new Point(eventArgs.X, eventArgs.Y); 

			Refresh(); 
 			UpdateTransparency(clientPoint);

 			bool retval = false;
			if ((eventArgs.Button & MouseButtons.Left) > 0) 
 			{
				for (int i = this.actions.Count - 1; i >= 0; i--) 
				{ 
					DynamicAction action = this.actions[i];
 					Rectangle actionBounds = GetActionBounds(i); 
					if (actionBounds.Contains(clientPoint))
 					{
 						for (int j = 0; j < action.Buttons.Count; j++)
						{ 
 							ActionButton actionButton = action.Buttons[j];
 
							if (actionButton.State != ActionButton.States.Disabled) 
							{
								Rectangle buttonBounds = GetButtonBounds(i, j); 

 								if (buttonBounds.Contains(clientPoint) && action.ActionType != DynamicAction.ActionTypes.TwoState)
									actionButton.State = ActionButton.States.Highlight;
 								else if (actionButton.State == ActionButton.States.Highlight) 
 									actionButton.State = ActionButton.States.Normal;
							} 
 						} 

						retval = true; 
					}
				}
 			}
 
			if (IsButtonDragged)
 				SetDraggedButton(-1, -1); 
 
 			return retval;
		} 

 		protected override bool OnMouseLeave()
		{
			ParentView.ShowInfoTip(String.Empty); 
			UpdateTransparency(Point.Empty);
 			Refresh(); 
			return false; 
 		}
 
 		protected override bool OnMouseCaptureChanged()
		{
 			if (IsButtonDragged)
				SetDraggedButton(-1, -1); 
			return false;
		} 
 
 		protected override bool OnPaintWorkflowAdornments(PaintEventArgs e, Rectangle viewPort, AmbientTheme ambientTheme)
        { 
			for (int i = 0; i < this.actions.Count; i++)
 			{
 				GraphicsContainer graphicsState = e.Graphics.BeginContainer();
				Point actionLocation = GetActionBounds(i).Location; 
 				e.Graphics.TranslateTransform(actionLocation.X, actionLocation.Y);
				this.actions[i].Draw(e.Graphics); 
				e.Graphics.EndContainer(graphicsState); 
			}
 			return false; 
		}
 		#endregion

 		#region Helpers 
		private void Refresh()
 		{ 
			WorkflowView parentView = ParentView; 
			for (int i = 0; i < this.actions.Count; i++)
				parentView.InvalidateClientRectangle(GetActionBounds(i)); 
 		}

		private Rectangle GetActionBounds(int actionIndex)
 		{ 
 			Rectangle bounds = new Rectangle(Point.Empty, ParentView.ViewPortSize);
			DynamicAction action = this.actions[actionIndex]; 
 
 			bounds.Inflate(-action.DockMargin.Width, -action.DockMargin.Height);
            return new Rectangle(ActivityDesignerPaint.GetRectangleFromAlignment(action.Doc----gnment, bounds, action.Bounds.Size).Location, action.Bounds.Size); 
        }

		private Rectangle GetButtonBounds(int actionIndex, int buttonIndex)
		{ 
			Rectangle bounds = GetActionBounds(actionIndex);
 			Rectangle buttonBounds = this.actions[actionIndex].GetButtonBounds(buttonIndex); 
			buttonBounds.Offset(bounds.Location); 
 			return buttonBounds;
 		} 

		private void UpdateTransparency(Point point)
 		{
			for (int i = 0; i < this.actions.Count; i++) 
			{
				float transparency = 0; 
 				if (!point.IsEmpty) 
				{
 					Rectangle actionBounds = GetActionBounds(i); 
 					if (actionBounds.Contains(point) || this.draggedActionIndex == i)
					{
 						transparency = 1.0f;
					} 
					else
					{ 
 						Rectangle rectangle = ParentView.ViewPortRectangle; 
						double distance = DesignerGeometryHelper.DistanceFromPointToRectangle(point, actionBounds);
 						if (distance > rectangle.Width / 3 || distance > rectangle.Height / 3) 
 						{
							transparency = 0.3f;
 						}
						else 
						{
							//Uncomment the following code for fluctuating transparency 
 							//1.0f - ((float)Convert.ToInt32(distance)) / Math.Max(ParentView.ViewPortSize.Width, ParentView.ViewPortSize.Height); 
							transparency = 1.0f;
 						} 
 					}
				}

 				this.actions[i].Transparency = transparency; 
			}
		} 
 
		private bool IsButtonDragged
 		{ 
			get
 			{
 				return (this.draggedActionIndex >= 0 && this.draggedButtonIndex >= 0);
			} 
 		}
 
		private void SetDraggedButton(int actionIndex, int buttonIndex) 
		{
			if (this.draggedActionIndex == actionIndex && this.draggedButtonIndex == buttonIndex) 
 				return;

			WorkflowView parentView = ParentView;
 			if (this.draggedActionIndex >= 0 && this.draggedButtonIndex >= 0) 
 			{
				if (this.draggedActionIndex < this.actions.Count) 
 					this.actions[this.draggedActionIndex].Buttons[this.draggedButtonIndex].State = ActionButton.States.Highlight; 

				this.draggedActionIndex = -1; 
				this.draggedButtonIndex = -1;
				parentView.Capture = false;
 				UpdateTransparency(parentView.PointToClient(Control.MousePosition));
			} 

 			this.draggedActionIndex = actionIndex; 
 			this.draggedButtonIndex = buttonIndex; 

			if (this.draggedActionIndex >= 0 && this.draggedButtonIndex >= 0) 
 				parentView.Capture = true;
		}
		#endregion
	} 
 	#endregion
 
	#region Class DynamicAction 
 	internal class DynamicAction : IDisposable
 	{ 
		#region Members and constructor
 		private static float DefaultTransparency = 0.0f;
		private static Size[] Sizes = new Size[] { new Size(20, 20), new Size(24, 24), new Size(28, 28), new Size(32, 32), new Size(36, 36) };
		private static Size[] Margins = new Size[] { new Size(1, 1), new Size(1, 1), new Size(2, 2), new Size(2, 2), new Size(3, 3) }; 
		internal enum ButtonSizes { Small = 0, SmallMedium = 1, Medium = 2, MediumLarge = 3, Large = 4 };
 		internal enum ActionTypes { Standard = 1, TwoState = 2 }; 
 
		private ItemList buttons = null;
 		private ButtonSizes buttonSizeType = ButtonSizes.Medium; 
 		private DesignerContentAlignment doc----gnment = DesignerContentAlignment.TopLeft;
		private float minimumTransparency = DynamicAction.DefaultTransparency;
 		private float transparency = DynamicAction.DefaultTransparency;
		private ActionTypes actionType = ActionTypes.Standard; 

		private Size borderSize = new Size(2, 2); 
		private Size dockMargin = DynamicAction.Sizes[(int)ButtonSizes.Medium]; 
 		private Size buttonSize = DynamicAction.Sizes[(int)ButtonSizes.Medium];
		private Size margin = DynamicAction.Margins[(int)ButtonSizes.Medium]; 

 		internal DynamicAction()
 		{
			this.buttons = new ItemList(this); 
 		}
 
        ~DynamicAction() 
        {
            Dispose(false); 
        }

		public void Dispose()
		{ 
            Dispose(true);
            GC.SuppressFinalize(this); 
		} 

        protected virtual void Dispose(bool disposing) 
        {
            foreach (ActionButton button in this.buttons)
                ((IDisposable)button).Dispose();
            this.buttons.Clear(); 
        }
 		#endregion 
 
		#region Properties and Methods
 		internal IList Buttons 
 		{
			get
 			{
				return this.buttons; 
			}
		} 
 
 		internal Size DockMargin
		{ 
 			get
 			{
				return this.dockMargin;
 			} 

			set 
			{ 
				this.dockMargin = value;
 			} 
		}

 		internal ActionTypes ActionType
 		{ 
			get
 			{ 
				return this.actionType; 
			}
		} 

 		internal ButtonSizes ButtonSize
		{
 			get 
 			{
				return this.buttonSizeType; 
 			} 

			set 
			{
				if (this.buttonSizeType == value)
 					return;
 
				this.buttonSizeType = value;
 				this.buttonSize = DynamicAction.Sizes[(int)this.buttonSizeType]; 
 				this.margin = DynamicAction.Margins[(int)this.buttonSizeType]; 
			}
 		} 

		internal DesignerContentAlignment Doc----gnment
		{
			get 
 			{
				return this.doc----gnment; 
 			} 

 			set 
			{
 				if (this.doc----gnment == value)
					return;
 
				this.doc----gnment = value;
			} 
 		} 

		internal float Transparency 
 		{
 			get
			{
 				return this.transparency; 
			}
 
			set 
			{
 				if (this.transparency == value) 
					return;

 				this.transparency = Math.Max(DynamicAction.DefaultTransparency, value);
 			} 
		}
 
 		internal void Draw(Graphics graphics) 
		{
            if (this.transparency == 0 || this.buttons.Count == 0) 
                return;

            ActivityDesignerPaint.Draw3DButton(graphics, null, Bounds, this.transparency - 0.1f, ButtonState.Normal);
 
            for (int i = 0; i < this.buttons.Count; i++)
			{ 
				Rectangle buttonBounds = GetButtonBounds(i); 
 				ActionButton button = this.buttons[i];
				if (button.StateImages.Length == 1) 
 				{
 					Image buttonImage = button.StateImages[0];
					if (button.State == ActionButton.States.Normal || button.State == ActionButton.States.Disabled)
 					{ 
						buttonBounds.Inflate(-2, -2);
						ActivityDesignerPaint.DrawImage(graphics, buttonImage, buttonBounds, new Rectangle(Point.Empty, buttonImage.Size), DesignerContentAlignment.Fill, transparency, (button.State == ActionButton.States.Disabled)); 
                    } 
					else
 					{ 
						ButtonState state = (button.State == ActionButton.States.Highlight) ? ButtonState.Normal : ButtonState.Pushed;
                        ActivityDesignerPaint.Draw3DButton(graphics, buttonImage, buttonBounds, this.transparency, state);
                    }
 				} 
 				else
				{ 
 					Image buttonImage = this.buttons[i].StateImages[(int)this.buttons[i].State]; 
					buttonBounds.Inflate(-2, -2);
					ActivityDesignerPaint.DrawImage(graphics, buttonImage, buttonBounds, new Rectangle(Point.Empty, buttonImage.Size), DesignerContentAlignment.Fill, this.transparency, false); 
                }
			}
 		}
 
		internal Rectangle Bounds
 		{ 
 			get 
			{
 				Size size = Size.Empty; 
				int buttonCount = Math.Max(1, this.buttons.Count);
				size.Width = (2 * borderSize.Width) + (buttonCount * this.buttonSize.Width) + ((buttonCount + 1) * this.margin.Width);
				size.Height = (2 * borderSize.Height) + this.buttonSize.Height + (2 * this.margin.Height);
 				return new Rectangle(Point.Empty, size); 
			}
 		} 
 
 		internal Rectangle GetButtonBounds(int buttonIndex)
		{ 
 			if (buttonIndex < 0 || buttonIndex >= this.buttons.Count)
				throw new ArgumentOutOfRangeException("buttonIndex");

			Rectangle rectangle = Rectangle.Empty; 
			rectangle.X = this.borderSize.Width + (buttonIndex * this.buttonSize.Width) + ((buttonIndex + 1) * this.margin.Width);
 			rectangle.Y = this.borderSize.Height + this.margin.Height; 
			rectangle.Size = this.buttonSize; 
 			return rectangle;
 		} 
		#endregion
 	}
	#endregion
 
	#region Class ActionButton
	internal sealed class ActionButton : IDisposable 
 	{ 
		#region Members, Constructor and Destruction
 		internal enum States { Normal = 0, Highlight = 1, Pressed = 2, Disabled = 3 }; 

 		internal event EventHandler StateChanged;

		private Image[] stateImages = null; 
 		private string description = String.Empty;
		private States buttonState = States.Normal; 
 
		internal ActionButton(Image[] stateImages)
		{ 
 			StateImages = stateImages;
		}

 		void IDisposable.Dispose() 
 		{
		} 
 		#endregion 

		#region Properties and Methods 
		internal Image[] StateImages
		{
 			get
			{ 
 				return this.stateImages;
 			} 
 
			set
 			{ 
				if (value == null)
					throw new ArgumentNullException("value");

			    if (value.Length != 1 && value.Length != 4) 
 					throw new ArgumentException(SR.GetString(SR.Error_InvalidStateImages), "value");
 
				this.stateImages = value; 
 				foreach (Image image in this.stateImages)
 				{ 
					Bitmap bitmap = image as Bitmap;
 					if (bitmap != null)
						bitmap.MakeTransparent(AmbientTheme.TransparentColor);
				} 
			}
 		} 
 
		internal States State
 		{ 
 			get
			{
 				return this.buttonState;
			} 

			set 
			{ 
 				if (this.buttonState == value)
					return; 

 				this.buttonState = value;

 				if (StateChanged != null) 
					StateChanged(this, EventArgs.Empty);
 			} 
		} 

		internal string Description 
		{
 			get
			{
 				return this.description; 
 			}
 
			set 
 			{
				this.description = value; 
			}
		}
 		#endregion
	} 
 	#endregion
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK