using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using DocToolkit; namespace DrawTools { partial class DrawArea : UserControl { #region Constructor public DrawArea() { InitializeComponent(); } #endregion Constructor #region Enumerations public enum DrawToolType { Pointer, Rectangle, Ellipse, Line, Polygon, NumberOfDrawTools }; #endregion #region Members private GraphicsList graphicsList; // list of draw objects // (instances of DrawObject-derived classes) private DrawToolType activeTool; // active drawing tool private Tool[] tools; // array of tools // Information about owner form private MainForm owner; private DocManager docManager; private ContextMenuStrip m_ContextMenu; private UndoManager undoManager; #endregion #region Properties /// /// Reference to the owner form /// public MainForm Owner { get { return owner; } set { owner = value; } } /// /// Reference to DocManager /// public DocManager DocManager { get { return docManager; } set { docManager = value; } } /// /// Active drawing tool. /// public DrawToolType ActiveTool { get { return activeTool; } set { activeTool = value; } } /// /// List of graphics objects. /// public GraphicsList GraphicsList { get { return graphicsList; } set { graphicsList = value; } } /// /// Return True if Undo operation is possible /// public bool CanUndo { get { if ( undoManager != null ) { return undoManager.CanUndo; } return false; } } /// /// Return True if Redo operation is possible /// public bool CanRedo { get { if (undoManager != null) { return undoManager.CanRedo; } return false; } } #endregion #region Other Functions /// /// Initialization /// /// /// public void Initialize(MainForm owner, DocManager docManager) { SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true); // Keep reference to owner form this.Owner = owner; this.DocManager = docManager; // set default tool activeTool = DrawToolType.Pointer; // create list of graphic objects graphicsList = new GraphicsList(); // Create undo manager undoManager = new UndoManager(graphicsList); // create array of drawing tools tools = new Tool[(int)DrawToolType.NumberOfDrawTools]; tools[(int)DrawToolType.Pointer] = new ToolPointer(); tools[(int)DrawToolType.Rectangle] = new ToolRectangle(); tools[(int)DrawToolType.Ellipse] = new ToolEllipse(); tools[(int)DrawToolType.Line] = new ToolLine(); tools[(int)DrawToolType.Polygon] = new ToolPolygon(); } /// /// Add command to history. /// public void AddCommandToHistory(Command command) { undoManager.AddCommandToHistory(command); } /// /// Clear Undo history. /// public void ClearHistory() { undoManager.ClearHistory(); } /// /// Undo /// public void Undo() { undoManager.Undo(); Refresh(); } /// /// Redo /// public void Redo() { undoManager.Redo(); Refresh(); } /// /// Set dirty flag (file is changed after last save operation) /// public void SetDirty() { DocManager.Dirty = true; } /// /// Right-click handler /// /// private void OnContextMenu(MouseEventArgs e) { // Change current selection if necessary Point point = new Point(e.X, e.Y); int n = GraphicsList.Count; DrawObject o = null; for (int i = 0; i < n; i++) { if (GraphicsList[i].HitTest(point) == 0) { o = GraphicsList[i]; break; } } if (o != null) { if (!o.Selected) GraphicsList.UnselectAll(); // Select clicked object o.Selected = true; } else { GraphicsList.UnselectAll(); } Refresh(); // in the case selection was changed // Show context menu. // Context menu items are filled from owner form Edit menu items. m_ContextMenu = new ContextMenuStrip(); int nItems = owner.ContextParent.DropDownItems.Count; // Read Edit items and move them to context menu. // Since every move reduces number of items, read them in reverse order. // To get items in direct order, insert each of them to beginning. for (int i = nItems - 1; i >= 0; i--) { m_ContextMenu.Items.Insert(0, owner.ContextParent.DropDownItems[i]); } // Show context menu for owner form, so that it handles items selection. // Convert point from this window coordinates to owner's coordinates. point.X += this.Left; point.Y += this.Top; m_ContextMenu.Show(owner, point); Owner.SetStateOfControls(); // enable/disable menu items // Context menu is shown, but owner's Edit menu is now empty. // Subscribe to context menu Closed event and restore items there. m_ContextMenu.Closed += delegate(object sender, ToolStripDropDownClosedEventArgs args) { if (m_ContextMenu != null) // precaution { nItems = m_ContextMenu.Items.Count; for (int k = nItems - 1; k >= 0; k--) { owner.ContextParent.DropDownItems.Insert(0, m_ContextMenu.Items[k]); } } }; } #endregion #region Event Handlers /// /// Draw graphic objects and /// group selection rectangle (optionally) /// private void DrawArea_Paint(object sender, PaintEventArgs e) { SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 255)); e.Graphics.FillRectangle(brush, this.ClientRectangle); if (graphicsList != null) { graphicsList.Draw(e.Graphics); } //DrawNetSelection(e.Graphics); brush.Dispose(); } /// /// Mouse down. /// Left button down event is passed to active tool. /// Right button down event is handled in this class. /// private void DrawArea_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) tools[(int)activeTool].OnMouseDown(this, e); else if (e.Button == MouseButtons.Right) OnContextMenu(e); } /// /// Mouse move. /// Moving without button pressed or with left button pressed /// is passed to active tool. /// private void DrawArea_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left || e.Button == MouseButtons.None) tools[(int)activeTool].OnMouseMove(this, e); else this.Cursor = Cursors.Default; } /// /// Mouse up event. /// Left button up event is passed to active tool. /// private void DrawArea_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) tools[(int)activeTool].OnMouseUp(this, e); } #endregion Event Handlers } }