using System; using System.Windows.Forms; namespace Netron.Diagramming.Core { // ---------------------------------------------------------------------- /// /// The base class for any tool . /// // ---------------------------------------------------------------------- public abstract class AbstractTool : ITool { #region Events // ------------------------------------------------------------------ /// /// Occurs when this tool is deactivated. /// // ------------------------------------------------------------------ public event EventHandler OnToolDeactivate; // ------------------------------------------------------------------ /// /// Occurs when this tool is activated. /// // ------------------------------------------------------------------ public event EventHandler OnToolActivate; #endregion #region Fields /// /// the Name field /// private string mName; /// /// the Enabled field /// private bool mEnabled = true; /// /// a pointer to the controller /// private IController mController; /// /// the tool's cursor /// private Cursor mCursor = Cursors.Default; /// /// whether the tool is currently active /// private bool mIsActive; /// /// keeps a reference to the previous cursor /// Cursor previousCursor; /// /// the suspend state of the tool /// private bool mIsSuspended; #endregion #region Properties /// /// Gets or sets a value indicating whether this instance is suspended. A tool enters in a suspended mode when another tool has been activated and disallows another to continue its normal activity. For example, the and are /// mutually exclusive and similarly for the drawing tools and the selection tool. /// This suspended state is independent of the and the states. /// /// /// true if this instance is suspended; otherwise, false. /// public bool IsSuspended { get { return mIsSuspended; } set { mIsSuspended = value; } } /// /// Gets or sets a value indicating whether this tool is active. /// /// true if this instance is active; otherwise, false. public bool IsActive { get { return mIsActive; } set { mIsActive = value; } } /// /// Gets or sets the name of the tool. /// /// The name. public string Name { get { return mName; } set { mName = value; } } /// /// Gets or sets the controller. /// /// The controller. public IController Controller { get { return mController; } set { mController = value; } } /// /// Gets or sets the cursor. /// /// The cursor. public Cursor Cursor { get { return mCursor; } set { mCursor = value; //prevCursor = Controller.View.CurrentCursor; Controller.View.CurrentCursor = value; } } /// /// Gets or sets the Enabled /// public bool Enabled { get { return this.mEnabled; } set { //disable the tool first if it is active if (!value && IsActive) { DeactivateTool(); } mEnabled = value; } } /// /// Gets a value indicating whether this tool excludes other tools. /// /// /// true if this instance is exclusive; otherwise, false. /// public virtual bool IsExclusive { get { return true; } } /// /// Gets or sets a value indicating whether this tool can activated. /// /// /// true if this instance can activate; otherwise, false. /// public virtual bool CanActivate { get { if (mEnabled) { return !IsActive; } else { return false; } } } #endregion #region Constructor /// /// Default constructor /// /// The name of the tool. public AbstractTool(string name) { this.mName = name; } #endregion #region Methods protected void RestoreCursor() { // I ran into an issue where the RectangleTool was activated, // nothing drawn, then the EllipseTool was activated. When // the EllipseTool was deactivated the cursor was set to the // previous cursor, which was the cursor for the RectangleTool. // Update: Rather than fixing it here, I changed // ControllerBase.ActivateTool(string) so it deactivates // the current tool first. //Controller.View.CurrentCursor = Cursors.Default; if (previousCursor != null) { if (Controller != null) { Controller.View.CurrentCursor = previousCursor; } previousCursor = null; } } // ------------------------------------------------------------------ /// /// Raises the event /// /// ConnectionCollection event argument // ------------------------------------------------------------------ public virtual void RaiseOnToolActivate(ToolEventArgs e) { EventHandler handler = OnToolActivate; if (handler != null) { handler(this, e); } } // ------------------------------------------------------------------ /// /// Raises the event. /// /// ConnectionCollection event argument // ------------------------------------------------------------------ public virtual void RaiseOnToolDeactivate(ToolEventArgs e) { EventHandler handler = OnToolDeactivate; if (handler != null) { handler(this, e); } } #region Activation & deactivation /// /// Deactivates the tool. /// /// public bool DeactivateTool() { if (IsActive) { OnDeactivateTool(); IsActive = false; RestoreCursor(); UnsuspendTools(); RaiseOnToolDeactivate(new ToolEventArgs(this)); return true; } return false; } /// /// Activates the tool. /// /// public bool ActivateTool() { //halt other actions SuspendOtherTools(); if (Enabled && !IsActive) { previousCursor = this.Controller.View.CurrentCursor; IsActive = true; OnActivateTool(); RaiseOnToolActivate(new ToolEventArgs(this)); } return IsActive; } /// /// Suspends the other tools. /// public void SuspendOtherTools() { foreach (ITool tool in Controller.Tools) { if (tool != this) tool.IsSuspended = true; } } /// /// Releases the previously suspeneded tools /// public void UnsuspendTools() { foreach (ITool tool in Controller.Tools) { tool.IsSuspended = false; } } #endregion /// /// Called when the tool is activated. /// protected virtual void OnActivateTool() { } /// /// Called when the tool is deactivated. /// protected virtual void OnDeactivateTool() { } /// /// Gets the service object of the specified type. /// /// An object that specifies the type of service object to get. /// /// A service object of type serviceType.-or- null if there is no service object of type serviceType. /// public object GetService(Type serviceType) { return null; } #endregion } }