/****************************************************************************************** *****************File Name:GraDrawTool.cs, Version 1.0, 8 November 2004******************** ******************************Author: Kanti Surapaneni************************************* **This class is defined to represent drawing method for different drawing type. ** ** The following classes are inherit from GraDrawTool-- DrawEnvMgr, GraDrawTool, ** ** GraDrawToolMgr, SelectDrawTool, RectDrawTool, FrameRectDrawTool, FillRectDrawTool, ** ** Line DrawTool, FramRectDrawtool, FillRectDrawTool. DrawEnvMgr class stores the ** ** global pen, brush and font objects that are used to draw the graphical elements. ** ** GraDrawToolMgr is the class that manages all these drawing tools classes. ** ** Its functions are mainly to add new draw tool, getting the toolbar that is selected ** ** so as to perform its function, setting the toolbar active. GraDrawTool class ** ** function is to make sure that the drawing operation is fulfilled. It sets the toolbar ** ** clicked to active and sends it to GraDrawToolMgr class. All the other DrawTools that ** ** are inherited from this class will perform their specific operation like selecting, ** ** drawing rectangle, line etc when that particular toolbar is selected. ** ** ** ******************************************************************************************/ /// using System; using System.Collections; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using System.Reflection; using System.IO; using GraEditor.Elements;//Elements include Line,Lines,Rectangle,Ellipse,Text,Image // Namespace DrawTool, include GraDrawTool,DrawEnvMgr,GraDrawToolMgr,LineDrawTool,LinesDrawTool, //FrameRectDrawTool, FillRectDrawTool, FrameEllipseDrawTool,FillEllipseDrawTool,ImageDrawTool,TextDrawTool,SelectDrawTool,GraDrawType namespace GraEditor.DrawTools { //Save Global pen, brush and font. We use these object when we draw graph element on canvas public class DrawEnvMgr { protected DrawEnvMgr() { this.pen = new Pen(Color.DarkGreen,1); //Set default pen this.brush = new SolidBrush(Color.DarkGreen);//Set default brush this.font = new Font("Arial",30); //Set default font } private static DrawEnvMgr instance;// instance of DrawEnvMgr //Get instance of DrawEnvMgr public static DrawEnvMgr Instance { get { if(instance == null) instance = new DrawEnvMgr(); return instance; } } protected Pen pen; //protected pen variable to save pen object //Pen property of DrawEnvMgr public Pen Pen { get { return pen; } } protected SolidBrush brush;//protected solidbrush variable to save brush object //Brush property of DrawEnvMgr public Brush Brush { get { return brush; } } //Set pen and brush color public Color Color { get { return pen.Color; } set { pen.Color = value; brush.Color = value; } } //Pen width property of DrawEnvMgr public int PenWidth { get { return (int)pen.Width; } set { pen.Width = value; } } protected Font font; //private font variable to save font //Font property of DrawEnvMgr public Font Font { get { return font ; } set { font = value; } } } //Specify how many draw type is included public enum GraDrawType { Select,Line,Lines,Freehand,Erase,FrameRect,FillRect,FrameEllipse,FillEllipse,Text,Image } //Abstract class for drawing operation. //SelectDrawTool(), LineDrawTool(), LinesDrawTool(), ImageDrawTool(), ImageDrawTool(), RectDrawTool(), //EllipseDrawTool() and TextDrawTool() are inherit from it. public abstract class GraDrawTool { /// /// /// /// public GraDrawTool() { } //Abstract variable. public abstract GraDrawType Type { get; } private GraDrawToolMgr drawToolMgr;//Private drawToolMgr variable of GraDrawTool //DrawTool Mgr property of GraDrawTool public GraDrawToolMgr DrawToolMgr { get { return drawToolMgr; } set { drawToolMgr = value;} } protected bool isDrawing; //When you are drawing,isDrawing is true. Else isDrawing is false private ToolBarButton tblBtn;//Save the ToolBar button //Toolbar button property of GraDrawTool public ToolBarButton TblBtn { get { return tblBtn; } set { tblBtn = value ;} } private Cursor oldCursor; protected Cursor toolCursor; public static event EventHandler ActiveStateChanged; public void OnActiveStateChanged() { if(ActiveStateChanged != null) ActiveStateChanged(this,EventArgs.Empty); } private bool isActive;//When the ToolBar button is pushdown, isActive is true. Else isActive is false //Active property of GraDrawTool public virtual bool IsActive { get { return isActive; } set { this.isActive = value; tblBtn.Pushed = this.isActive; OnActiveStateChanged(); if(this.toolCursor != null) { if(this.isActive) { this.oldCursor = Canvas.Instance.MainView.Cursor; Canvas.Instance.MainView.Cursor = this.toolCursor; } else Canvas.Instance.MainView.Cursor = this.oldCursor; } } } public virtual string Tip { get { return "";} } public static int gridSize = 5;//Set the small distance you can draw. If mouse moves smaller distance than gridSize, we think it do not move public Cursor CreateCursor(string cursorName) { Assembly a = Assembly.GetExecutingAssembly(); Stream s = a.GetManifestResourceStream(cursorName); return new Cursor(s); } //Round calculation of mouse movement.Mouse must move at least 6 pixel every time. public static Point GetRoundPoint(Point pt) { int x = (pt.X+gridSize/2)/gridSize*gridSize; int y = (pt.Y+gridSize/2)/gridSize*gridSize; return new Point(x,y); } public static Point RegularEndPt(Point ptStart, Point ptEnd) { int sx = Math.Abs(ptEnd.X - ptStart.X); int sy = Math.Abs(ptEnd.Y - ptStart.Y); int s = Math.Max(sx,sy); int x =0; int y =0; if(ptEnd.X > ptStart.X) x = ptStart.X + s; else x = ptStart.X - s; if(ptEnd.Y > ptStart.Y) y = ptStart.Y + s; else y = ptStart.Y - s; return new Point(x,y); } public static Rectangle CreateValidRect(Point pt1, Point pt2) { int x = Math.Min(pt1.X,pt2.X);//Judge whether the current x position is at the right of the start point or not int y = Math.Min(pt1.Y,pt2.Y);//Judge whether the current y position is under the start point or no int w = Math.Abs(pt2.X - pt1.X);//calculate the width of rectangle int h = Math.Abs(pt2.Y - pt1.Y);//calculate the height of rectangle return new Rectangle(new Point(x,y),new Size(w,h)); } public abstract void OnMouseDown(MouseEventArgs e);//abstract OnMouseDown event public abstract void OnMouseMove(MouseEventArgs e);//abstract OnMouseMove event public abstract void OnMouseUp(MouseEventArgs e);//abstract OnMouseUp event public virtual void OnDoubleClick(EventArgs e)//abstract OnDoubleClick event { } } //Manage draw tools, add new draw tool type public class GraDrawToolMgr { protected GraDrawToolMgr() { toolMap = new Hashtable(); //Use hash table to reach the draw tool, it is fast than using vector.toolMap(draw tool type)=draw tool. } private static GraDrawToolMgr instance;//instance of GraDrawToolMgr //Return the instance of GraDrawToolMgr public static GraDrawToolMgr Instance { get { if(instance == null) instance = new GraDrawToolMgr(); return instance; } } private Hashtable toolMap; // private hash table to save draw tool types //Return draw tool public GraDrawTool this[GraDrawType t] { get { return toolMap[t] as GraDrawTool; } set { toolMap[t] = value; } } //Add draw tool to toolMap public void AddDrawTool(GraDrawTool drawTool) { if(drawTool == null) return; drawTool.DrawToolMgr = this; toolMap[drawTool.Type] = drawTool; } private GraDrawTool activeDrawTool;//Save the current draw tool //Active draw tool property of GraDrawToolMgr public GraDrawTool ActiveDrawTool { get { return activeDrawTool; } } //Set the current draw tool public void SetActiveTool(GraDrawType t) { GraDrawTool clickDrawTool = this[t];//Get which Toolbar button is clicked if(this.activeDrawTool == clickDrawTool)//Reclick the same Toolbar button.Disable the last cliked Toolbar button { this.activeDrawTool.IsActive = false; this.activeDrawTool = null; return; } if(this.activeDrawTool != null)//Click a new Toolbar button this.activeDrawTool.IsActive = false; this.activeDrawTool = clickDrawTool;//Set the new clicked Toolbar button as current one this.activeDrawTool.IsActive = true; } } //It is inherited from GraDrawTool(). It is used for selecting actions. //When we use mouse to select an area, we use this class display some temporary rectangles before we decide the end point of select public class SelectDrawTool : GraDrawTool { protected SelectDrawTool() :base() { this.isSelectRectVisible = false;//Do not display the rectangle frame } //Reset the select area public void ReSet() { this.selectRectGra = null; this.isSelectRectVisible = false; } //Specify select type public override GraDrawType Type { get { return GraDrawType.Select; } } private static SelectDrawTool instance;//instance of SelectDrawTool //Return instance of SelectDrawTool public static SelectDrawTool Instance { get { if(instance == null) instance = new SelectDrawTool(); return instance; } } //Select area.Size and position of select public Rectangle SelectRect { get { if(selectRectGra == null) return Rectangle.Empty; else return selectRectGra.Rect; } } public event EventHandler StateChanged; public void OnStateChanged() { if(StateChanged != null) StateChanged(this,EventArgs.Empty); } private RectGra selectRectGra;//private RectGra variable so save select area public RectGra SelectRectGra { get { return this.selectRectGra; } } private Point ptStart; private Point ptPre;//Temporary point use for round private bool isSelectRectVisible;//Frame of select is visible or not //Cancel the selected operation private void ClerSelectedRect() { if(!this.isSelectRectVisible) return; Canvas.Instance.GraList.Remove(this.selectRectGra); //Remove the select object from GraList this.isSelectRectVisible = false; Canvas.Instance.Update();//Update the canvas } public override void OnMouseDown(MouseEventArgs e) { ptStart = new Point(e.X,e.Y);//Start point of select ptStart = GetRoundPoint(ptStart);//Round the start point ptPre = ptStart;//Temporary point use for round //Convert the postion to the original coordinate when you zoom in or zoom out ptStart = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStart); if(e.Button == MouseButtons.Right)//right click mouse button { return; } this.ClerSelectedRect();//Cancel the selected operation this.isDrawing = true; //Drawing status //Construct a pen object to draw the select frame using(Pen p = new Pen(Color.Black,1)) { p.DashStyle = DashStyle.Dot;//select frame is dash line selectRectGra = new RectGra(p,null, GraDrawMode.Frame,new Rectangle(ptStart,new Size(0,0)));//Use selectRectGra to save the positon and size of Select area } Canvas.Instance.GraList.Add(selectRectGra);//Add select to GraList this.isSelectRectVisible = true;//Set select frame visible Canvas.Instance.Update();//Update the canvas } public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing) return; Point ptEnd = new Point(e.X,e.Y);//Save the current position of mouse ptEnd = GetRoundPoint(ptEnd);//Round the end point. The min mouse movement distance is 6. if(ptEnd == ptPre)//Movement distance < 6 return; ptPre = ptEnd;//Save end point as a temporary point ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEnd);//Get current posion.Convert to orginal coordiante when zoom in or zoom out if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { ptEnd = RegularEndPt(ptStart,ptEnd); } //Set the position and size of select area selectRectGra.Rect = CreateValidRect(ptStart,ptEnd); Canvas.Instance.Update();//Update canvas } public override void OnMouseUp(MouseEventArgs e) { if(this.isDrawing) { this.isDrawing = false;//Disable the drawing status Rectangle r = this.selectRectGra.Rect; if(r.Width <5 || r.Height <5) { ClerSelectedRect(); this.selectRectGra = null; } else OnStateChanged(); } } private Bitmap copyImage;//Save the select area as a picture public Bitmap CopyImage { get { return this.copyImage; } } // private ToolBarButton cutBtn; // public ToolBarButton CutBtn // { // get { return cutBtn;} // set // { // // cutBtn = value; // if(this.selectRectGra == null) // cutBtn.Enabled = false; // } // } // private ToolBarButton copyBtn; // public ToolBarButton CopyBtn // { // get { return copyBtn;} // set // { // copyBtn = value; // if(this.selectRectGra == null) // copyBtn.Enabled = false; // // } // } //Cut operation public void Cut() { if(!this.CreateCopyImage()) return; // Color c = Canvas.Instance.BackColor;//Background color Brush b = new SolidBrush(c); Pen p = new Pen(c); EraseRectGra rGra = new EraseRectGra(p,b,GraDrawMode.Frame | GraDrawMode.Fill, this.selectRectGra.Rect);//Set the select area with background color b.Dispose();//Dispose the brush object p.Dispose();//Dispose the pen object Canvas.Instance.AddGra(rGra); this.selectRectGra = null; OnStateChanged(); } private bool CreateCopyImage() { if(this.selectRectGra == null) return false;; this.ClerSelectedRect();//Cancel the select area Canvas canvas = Canvas.Instance;//Get instance of canvas Rectangle destRect = new Rectangle(new Point(0,0),this.selectRectGra.Rect.Size);//Paste the cut area to this rectangle area Rectangle souRect = this.selectRectGra.Rect;//Save position and size of select area in souRect souRect = canvas.MainView.ConvertCanvasToViewBitmapRect(souRect);//Convert to orginal coordinate when you zoom in or zoom out this.copyImage = new Bitmap(destRect.Width,destRect.Height);//construct a image //construct a graphic object from copyImage using(Graphics g = Graphics.FromImage(this.copyImage)) { //Draw the graph on destination area g.DrawImage(MainView.ViewBitmap,destRect, souRect.X,souRect.Y,souRect.Width,souRect.Height,GraphicsUnit.Pixel); } this.copyImage.MakeTransparent(Canvas.Instance.BackColor);// Make the copyImage transparent return true; } //Copy operation public void Copy() { if(!this.CreateCopyImage()) return ; this.selectRectGra = null; OnStateChanged(); // Color c = Canvas.Instance.BackColor;//Background color // Brush b = new SolidBrush(c); // Pen p = new Pen(c); // RectGra rGra = new RectGra(p,b,GraDrawMode.Frame | GraDrawMode.Fill, // this.selectRectGra.Rect);//Set the select area with background color // // b.Dispose();//Dispose the brush object // p.Dispose();//Dispose the pen object // // canvas.GraList.Add(rGra);//Add to GraList // canvas.Update();//Update canvas } private Point contextMenuMousePos; //position of pop-up menu public Point ContextMenuMousePos { get { return contextMenuMousePos; } set { contextMenuMousePos = value; } } //Paste operation public void Paste( ) { this.ClerSelectedRect();//Cancel the select area if(this.copyImage == null)//Not did cut or copy operation return; //Convert the paste position.Convert to orginal coordinate when you zoom in or zoom out Point pastePos = Canvas.Instance.MainView.ConvertViewToCanvasPt(this.contextMenuMousePos); //Save select area as a image into imGra ImageGra imGra = new ImageGra(this.copyImage.Clone() as Image, new Rectangle(pastePos,new Size(this.copyImage.Width,this.copyImage.Height))); //Canvas.Instance.GraList.Add(imGra);//Add to GraList //Canvas.Instance.Update();//Update canvas Canvas.Instance.AddGra(imGra); } //Active property of SelectDrawTool public override bool IsActive { get { return base.IsActive;//Return the IsActive of GraDrawTool } set { base.IsActive = value; //Cancel select operation without doing cut,move or paste if(!base.IsActive && this.selectRectGra != null) { this.ClerSelectedRect();//Cancel the select area } } } } //It inherit from GraDrawTool(). It is used for drawing rectangle actions. //When we mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public abstract class RectDrawTool : GraDrawTool { public RectDrawTool(GraDrawMode drawMode)//Get the draw mode:frame or solid :base() { this.drawMode = drawMode; this.toolCursor = Cursors.Cross; } protected GraDrawMode drawMode;//protected drawMode variable to save the draw mode public override string Tip { get { return "Pressed 'Shift' key to draw a quare"; } } private RectGra rectGra;//Save the rectangle private Point ptStart;//Start postion for drawing private Point ptPre; ////Temporary point use for round public override void OnMouseDown(MouseEventArgs e) { this.isDrawing = true;//Drawing status ptStart = new Point(e.X,e.Y);//Get new start point ptStart = GetRoundPoint(ptStart);//Round the start point ptPre = ptStart;//Temporary point use for round //Convert the start position to original coordinate when you zoom in or zoom out ptStart = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStart); //Construct a temporary rectangle to display rectGra = new RectGra(DrawEnvMgr.Instance.Pen,DrawEnvMgr.Instance.Brush, drawMode,new Rectangle(ptStart,new Size(0,0))); //Canvas.Instance.GraList.Add(rectGra);//Add to GraList //Canvas.Instance.Update();//Update canvas Canvas.Instance.AddGra(rectGra); } public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing)//Not drawing return; Point ptEnd = new Point(e.X,e.Y);//Get end point of temporary rectangle ptEnd = GetRoundPoint(ptEnd);//Round the end point. The min mouse movement distance is 6. if(ptEnd == ptPre)//Movement distance < 6 return; ptPre = ptEnd;//Save end point as a temporary point //Convert the end position to ordinal coordinate when you zoom in or zoom out ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEnd); if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { ptEnd = RegularEndPt(ptStart,ptEnd); } rectGra.Rect = CreateValidRect(ptStart,ptEnd); Canvas.Instance.Update();//Update canvas } public override void OnMouseUp(MouseEventArgs e) { this.isDrawing = false;//Not Drawing } } //It inherits from RecaDrawTool(). It is used for drawing frame rectangle. //When we use mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public class FrameRectDrawTool : RectDrawTool { /// /// /// public FrameRectDrawTool() :base(GraDrawMode.Frame) { } //Specify the draw type: frame rectangle public override GraDrawType Type { get { return GraDrawType.FrameRect; } } } //It inherit from RecaDrawTool(). It is used for drawing solid rectangle. //When we use mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public class FillRectDrawTool : RectDrawTool { public FillRectDrawTool() :base(GraDrawMode.Fill) { } //Specify the draw type: solid rectangle public override GraDrawType Type { get { return GraDrawType.FillRect; } } } //It inherit from GraDrawTool(). It is used for drawing rectangle actions. //When we mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public abstract class EllipseDrawTool : GraDrawTool { public EllipseDrawTool(GraDrawMode drawMode)//Get the draw mode:frame or solid :base() { this.drawMode = drawMode; } protected GraDrawMode drawMode;//protected drawMode variable to save the draw mode private EllipseGra ellipseGra;//Save the rectangle private Point ptStart;//Start postion for drawing private Point ptPre; ////Temporary point use for round public override string Tip { get { return "Pressed 'Shift' key to draw a circle"; } } public override void OnMouseDown(MouseEventArgs e) { this.isDrawing = true;//Drawing status ptStart = new Point(e.X,e.Y);//Get new start point ptStart = GetRoundPoint(ptStart);//Round the start point ptPre = ptStart;//Temporary point use for round //Convert the start position to original coordinate when you zoom in or zoom out ptStart = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStart); //Construct a temporary rectangle to display ellipseGra = new EllipseGra(DrawEnvMgr.Instance.Pen,DrawEnvMgr.Instance.Brush, drawMode,new Rectangle(ptStart,new Size(0,0))); //Canvas.Instance.GraList.Add(ellipseGra);//Add to GraList //Canvas.Instance.Update();//Update canvas Canvas.Instance.AddGra(ellipseGra); } public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing)//Not drawing return; Point ptEnd = new Point(e.X,e.Y);//Get end point of temporary rectangle ptEnd = GetRoundPoint(ptEnd);//Round the end point. The min mouse movement distance is 6. if(ptEnd == ptPre)//Movement distance < 6 return; ptPre = ptEnd;//Save end point as a temporary point //Convert the end position to orginal coordinate when you zoom in or zoom out ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEnd); if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { ptEnd = RegularEndPt(ptStart,ptEnd); } ellipseGra.Rect = CreateValidRect(ptStart,ptEnd); Canvas.Instance.Update();//Update canvas } public override void OnMouseUp(MouseEventArgs e) { this.isDrawing = false;//Not Drawing } } //It inherit from RecaDrawTool(). It is used for drawing frame rectangle. //When we use mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public class FrameEllipseDrawTool : EllipseDrawTool { /// /// /// public FrameEllipseDrawTool() :base(GraDrawMode.Frame) { } //Specify the draw type: frame rectangle public override GraDrawType Type { get { return GraDrawType.FrameEllipse; } } } //It inherit from RecaDrawTool(). It is used for drawing solid rectangle. //When we use mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public class FillEllipseDrawTool : EllipseDrawTool { public FillEllipseDrawTool() :base(GraDrawMode.Fill) { } //Specify the draw type: solid rectangle public override GraDrawType Type { get { return GraDrawType.FillEllipse; } } } //It inherit from GraDrawTool(). It is used for insert image actions. //When we mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public class ImageDrawTool : GraDrawTool { public ImageDrawTool()//Get the draw mode:frame or solid :base() { this.toolCursor = Cursors.Cross; } public override GraDrawType Type { get { return GraDrawType.Image; } } private RectGra rectGra;//Save the rectangle private Point ptStart;//Start postion for drawing private Point ptPre; ////Temporary point use for round public override void OnMouseDown(MouseEventArgs e) { this.isDrawing = true;//Drawing status ptStart = new Point(e.X,e.Y);//Get new start point ptStart = GetRoundPoint(ptStart);//Round the start point ptPre = ptStart;//Temporary point use for round //Convert the start position to original coordinate when you zoom in or zoom out ptStart = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStart); //Construct a temporary rectangle to display rectGra = new RectGra(Pens.DarkBlue,null, GraDrawMode.Frame,new Rectangle(ptStart,new Size(0,0))); Canvas.Instance.GraList.Add(rectGra);//Add to GraList Canvas.Instance.Update();//Update canvas } public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing)//Not drawing return; Point ptEnd = new Point(e.X,e.Y);//Get end point of temporary rectangle ptEnd = GetRoundPoint(ptEnd);//Round the end point. The min mouse movement distance is 6. if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { ptEnd = RegularEndPt(ptStart,ptEnd); } if(ptEnd == ptPre)//Movement distance < 6 return; ptPre = ptEnd;//Save end point as a temporary point //Convert the end position to original coordinate when you zoom in or zoom out ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEnd); rectGra.Rect = CreateValidRect(ptStart,ptEnd); Canvas.Instance.Update();//Update canvas } public override void OnMouseUp(MouseEventArgs e) { if(!this.isDrawing) return; this.isDrawing = false;//Not Drawing if(rectGra.Rect.Width <5 && rectGra.Rect.Height <5) return; Canvas.Instance.GraList.Remove(rectGra); OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "Bitmap files (*.bmp)|*.bmp|Jpg files (*.jpg)|*.jpg|All files (*.*)|*.*" ; dlg.FilterIndex = 1 ; dlg.RestoreDirectory = true ; if(dlg.ShowDialog() == DialogResult.OK) { Bitmap bmp = new Bitmap(dlg.FileName); if(bmp != null) { ImageGra imageGra = new ImageGra(bmp,rectGra.Rect); //Canvas.Instance.GraList.Add(imageGra);//Add to GraList //Canvas.Instance.Update();//Update canvas Canvas.Instance.AddGra(imageGra); } } this.rectGra = null; } } //It inherit from GraDrawTool(). It is used for insert text actions. //When we mouse to draw a rectangle, we need display some temporary rectangle before we decide the end point of the rectangle. public class TextDrawTool : GraDrawTool { protected TextDrawTool( )//Get the draw mode:frame or solid :base() { this.toolCursor = Cursors.Cross; } private static TextDrawTool instance; public static TextDrawTool Instance { get { if(instance == null) instance = new TextDrawTool(); return instance; } } public override GraDrawType Type { get { return GraDrawType.Text; } } public override string Tip { get { return "Click 'Enter' key to stop,click 'Esc' Key to cancel"; } } public override bool IsActive { get { return base.IsActive; } set { base.IsActive = value; if(!base.IsActive) { if(this.textBox != null) { this.EndTextEditing(true); } } } } private RectGra rectGra;//Save the rectangle private Point ptStart;//Start postion for drawing private Point ptEnd; private Point ptPre; ////Temporary point use for round private Point ptStartView; private Point ptEndView; public override void OnMouseDown(MouseEventArgs e) { if(this.isJustEditing) { Point pt = new Point(e.X,e.Y); if(!textBox.Bounds.Contains(pt)) this.EndTextEditing(true); return ; } this.isDrawing = true;//Drawing status ptStartView = new Point(e.X,e.Y);//Get new start point ptStartView = GetRoundPoint(ptStartView);//Round the start point ptPre = ptStartView;//Temporary point use for round //Convert the start position to original coordinate when you zoom in or zoom out ptStart = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStartView); //Construct a temporary rectangle to display rectGra = new RectGra(Pens.DarkBlue,null, GraDrawMode.Frame,new Rectangle(ptStart,new Size(0,0))); Canvas.Instance.GraList.Add(rectGra);//Add to GraList Canvas.Instance.Update();//Update canvas // } public override void OnMouseMove(MouseEventArgs e) { if(this.isJustEditing) return; if(!this.isDrawing)//Not drawing return; ptEndView = new Point(e.X,e.Y);//Get end point of temporary rectangle ptEndView = GetRoundPoint(ptEndView);//Round the end point. The min mouse movement distance is 6. if(ptEndView == ptPre)//Movement distance < 6 return; ptPre = ptEndView;//Save end point as a temporary point //Convert the end position to original coordinate when you zoom in or zoom out ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEndView); rectGra.Rect = CreateValidRect(ptStart,ptEnd); Canvas.Instance.Update();//Update canvas } private bool isJustEditing; private TextBox textBox; public override void OnMouseUp(MouseEventArgs e) { if(this.isJustEditing) return; if(!this.isDrawing) return; this.isDrawing = false;//Not Drawing if(rectGra.Rect.Width <5 && rectGra.Rect.Height <5) return; Canvas.Instance.GraList.Remove(rectGra); textBox = new TextBox(); textBox.Multiline = true; textBox.BackColor = Canvas.Instance.BackColor; textBox.ForeColor = DrawEnvMgr.Instance.Color; Rectangle viewRect = CreateValidRect(ptStartView,ptEndView); float s = Canvas.Instance.MainView.ViewMatrix.Elements[0]; textBox.Bounds = viewRect; Font f =DrawEnvMgr.Instance.Font; textBox.Font = new Font(f.Name,f.Size*s); Canvas.Instance.MainView.Controls.Add(textBox); textBox.Focus(); textBox.KeyDown +=new KeyEventHandler(textBox_KeyDown); this.isJustEditing = true; //FontDialog dlg = new FontDialog(); //instantiating a new fontdialog box //dlg.Font = DrawEnvMgr.Instance.Font; //if(DialogResult.OK == dlg.ShowDialog()) //{ // DrawEnvMgr.Instance.Font = dlg.Font; // assigning the font selected by the user to DrawEnvMgr.Instance.Font //} } public void EndTextEditing(bool isValid) { if(this.textBox == null) return; this.isJustEditing = false; Canvas.Instance.MainView.Controls.Remove(textBox); if(isValid && !(textBox.Text == null || textBox.Text.Length == 0)) { TextGra textGra = new TextGra(textBox.Text,DrawEnvMgr.Instance.Font, DrawEnvMgr.Instance.Brush,rectGra.Rect); //Canvas.Instance.GraList.Add(textGra);//Add to GraList //Canvas.Instance.Update();//Update canvas Canvas.Instance.AddGra(textGra); this.rectGra = null; } this.textBox = null; Canvas.Instance.Update(); } private void textBox_KeyDown(object sender, KeyEventArgs e) { if(this.textBox == null) return; //Click 'Enter' when you complete input text if(e.KeyCode == Keys.Enter) { this.EndTextEditing(true); } else if(e.KeyCode == Keys.Escape) { this.EndTextEditing(false); } } } //It inherit from GraDrawTool(). It is used for drawing line actions. //When we mouse to draw a line, we need display some temporary lines before we decide the end point of the line public class LineDrawTool : GraDrawTool { public LineDrawTool() :base() { this.toolCursor = Cursors.Cross; } //Specify the draw type: line public override GraDrawType Type { get { return GraDrawType.Line; } } public override string Tip { get { return "Pressed 'Shift' key to draw horizontal or vertical line"; } } private LineGra lineGra;//Save the start point,end point,color and width of line private Point ptStart; private Point ptPre;//Temporary point use for round public override void OnMouseDown(MouseEventArgs e) { this.isDrawing = true;//Drawing status ptStart = new Point(e.X,e.Y);//Start point ptStart = GetRoundPoint(ptStart);//Round point ptPre = ptStart;//Temporary point use for round //Convert the start position to original coordinate when you zoom in or zoom out Point pt = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStart); //Construct a temporary line to display lineGra = new LineGra(DrawEnvMgr.Instance.Pen, pt,pt); //Canvas.Instance.GraList.Add(lineGra);//Add to GraList //Canvas.Instance.Update();//Update canvas Canvas.Instance.AddGra(lineGra); } public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing)//Drawing Status=false return; Point ptEnd = new Point(e.X,e.Y);//Temporary end point ptEnd = GetRoundPoint(ptEnd);//Round the end point. The min mouse movement distance is 6. if((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { int sx = Math.Abs(ptEnd.X - ptStart.X); int sy = Math.Abs(ptEnd.Y - ptStart.Y); if(sy < sx) ptEnd.Y = ptStart.Y; else ptEnd.X = ptStart.X; } if( ptEnd == ptPre)//Movement distance < 6 return; ptPre = ptEnd;//Save end point as a temporary point //Convert the end position to original coordinate when you zoom in or zoom out ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEnd); lineGra.EndPt = ptEnd;//Set the end point to LineGra Canvas.Instance.Update();//Update canvas } public override void OnMouseUp(MouseEventArgs e) { this.isDrawing = false;//Drawing status = false } } //It inherit from GraDrawTool(). It is used for drawing lines actions. //When we mouse to draw a line, we need display some temporary lines before we decide the end point of the line public class LinesDrawTool : GraDrawTool { public LinesDrawTool() :base() { this.ptList = new ArrayList(); this.toolCursor = Cursors.Cross; } //Specify the draw type: line public override GraDrawType Type { get { return GraDrawType.Lines; } } public override string Tip { get { return "Double click left mouse button to finish drawing lines"; } } private LinesGra linesGra;//Save the start point,end point,color and width of line private ArrayList ptList; public override void OnMouseDown(MouseEventArgs e) { Point ptStart = new Point(e.X,e.Y);//Start point ptStart = GetRoundPoint(ptStart);//Round point Point ptPre = ptStart;//Temporary point use for round //Convert the start position to orginal coordinate when you zoom in or zoom out Point pt = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStart); if( !this.isDrawing) { //start creating lines graph element this.isDrawing = true;//Drawing status ptList.Clear(); ptList.Add(pt); //Construct a temporary line to display linesGra = new LinesGra(DrawEnvMgr.Instance.Pen, new Point[]{pt}); Canvas.Instance.GraList.Add(linesGra);//Add to GraList Canvas.Instance.IsModified = true; } else { ptList.Add(pt); Point[] pts = ptList.ToArray(typeof(Point)) as Point[]; linesGra.Pts = pts; } Canvas.Instance.Update();//Update canvas } private Point ptPre;//Temproary point use for round public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing)//Drawing Status=false return; Point ptEnd = new Point(e.X,e.Y);//Temproary end point ptEnd = GetRoundPoint(ptEnd);//Round the end point. The min mouse movement distance is 6. if( ptEnd == ptPre)//Movement distance < 6 return; ptPre = ptEnd;//Save end point as a temproary point //Convert the end position to orginal coordinate when you zoom in or zoom out ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEnd); if(ptList.Count > 1) ptList.RemoveAt(ptList.Count-1); ptList.Add(ptEnd); Point[] pts = ptList.ToArray(typeof(Point)) as Point[]; linesGra.Pts = pts;//Set the end point to LineGra Canvas.Instance.Update();//Update canvas } public override void OnMouseUp(MouseEventArgs e) { //Do nothing } public override void OnDoubleClick(EventArgs e) { this.isDrawing = false;//Drawing status = false } } //It inherit from GraDrawTool(). It is used for drawing lines actions. //When we mouse to erase public class EraseDrawTool : GraDrawTool { public EraseDrawTool() :base() { this.ptList = new ArrayList(); this.toolCursor = CreateCursor("Icon.EraseCursor.cur"); //Cursor } //Specify the draw type: line public override GraDrawType Type { get { return GraDrawType.Erase; } } private ArrayList ptList; private Point ptStart; private Point ptStartView; private Point ptPreView;//Temporary point use for round public override void OnMouseDown(MouseEventArgs e) { ptStartView = new Point(e.X,e.Y);//Start point ptStart = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStartView); if( !this.isDrawing) { //start creating lines graph element Color eraseColor=Canvas.Instance.BackColor; float sx = Canvas.Instance.MainView.ViewMatrix.Elements[0]; float w = sx*10; this.erasePen = new Pen(eraseColor,w); this.isDrawing = true;//Drawing status ptList.Clear(); ptList.Add(ptStart); ptPreView = ptStartView; } } private Pen erasePen; public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing)//Drawing Status=false return; Point ptCurView = new Point(e.X,e.Y);//Temporary end point //Convert the end position to original coordinate when you zoom in or zoom out Point ptCur = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptCurView); ptList.Add(ptCur); using(Graphics g = Canvas.Instance.MainView.CreateGraphics()) { Rectangle rc = new Rectangle(new Point(0,0),Canvas.Instance.Size); rc = Canvas.Instance.MainView.ConvertCanvasToViewBitmapRect(rc); Region r = new Region(rc); Region old = g.Clip; g.Clip = r; g.DrawLine(this.erasePen,ptPreView,ptCurView); g.Clip = old; } ptPreView = ptCurView; } public override void OnMouseUp(MouseEventArgs e) { if(this.isDrawing) { this.isDrawing = false;//Drawing status = false Point[] pts = ptList.ToArray(typeof(Point)) as Point[]; EraseLinesGra linesGra = new EraseLinesGra(this.erasePen,pts); Canvas.Instance.GraList.Add(linesGra); Canvas.Instance.IsModified = true; } } } // public class EraseDrawTool : GraDrawTool // { // // public EraseDrawTool() // :base() // { // this.ptList = new ArrayList(); // toolCursor = CreateCursor("Icon.EraseCursor.cur"); // // //Cursor // } // // //Specify the draw type: line // public override GraDrawType Type // { // get // { // return GraDrawType.Erase; // } // } // // // // // private EraseLinesGra linesGra;//Save the start point,end point,color and width of line // // private ArrayList ptList; // // // // public override void OnMouseDown(MouseEventArgs e) // { // Point ptStart = new Point(e.X,e.Y);//Start point // ptStart = GetRoundPoint(ptStart);//Round point // Point ptPre = ptStart;//Temporary point use for round // //Convert the start position to orginal coordinate when you zoom in or zoom out // Point pt = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStart); // // if( !this.isDrawing) // { // //start creating lines graph element // // this.isDrawing = true;//Drawing status // ptList.Clear(); // ptList.Add(pt); // // // //Construct a temporary line to display // Color color=Canvas.Instance.BackColor; // // linesGra = new EraseLinesGra(new Pen(color,10), // new Point[]{pt}); // // Canvas.Instance.GraList.Add(linesGra);//Add to GraList // Canvas.Instance.IsModified = true; // } // else // { // ptList.Add(pt); // Point[] pts = ptList.ToArray(typeof(Point)) as Point[]; // linesGra.Pts = pts; // } // // Canvas.Instance.Update();//Update canvas // // } // // private Point ptPre;//Temporary point use for round // // // public override void OnMouseMove(MouseEventArgs e) // { // if(!this.isDrawing)//Drawing Status=false // return; // Point ptEnd = new Point(e.X,e.Y);//Temporary end point // ptEnd = GetRoundPoint(ptEnd);//Round the end point. The min mouse movement distance is 6. // // if( ptEnd == ptPre)//Movement distance < 6 // return; // // ptPre = ptEnd;//Save end point as a temproary point // // //Convert the end position to orginal coordinate when you zoom in or zoom out // ptEnd = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptEnd); // // // ptList.Add(ptEnd); // // Point[] pts = ptList.ToArray(typeof(Point)) as Point[]; // // linesGra.Pts = pts;//Set the end point to LineGra // // Canvas.Instance.Update();//Update canvas // // // } // // // public override void OnMouseUp(MouseEventArgs e) // { // if(this.isDrawing) // { // this.isDrawing = false;//Drawing status = false // // DrawEnvMgr.Instance.Pen.Color=color; // // DrawEnvMgr.Instance.Pen.Width=width; // } // } // // // } //It inherit from GraDrawTool(). It is used for drawing lines actions. //When we mouse to freehand drawing public class FreehandDrawTool : GraDrawTool { public FreehandDrawTool() :base() { this.ptList = new ArrayList(); this.toolCursor = Cursors.Cross; //Cursor } //Specify the draw type: line public override GraDrawType Type { get { return GraDrawType.Freehand; } } private ArrayList ptList; private Point ptStart; private Point ptStartView; private Point ptPreView;//Temporary point use for round public override void OnMouseDown(MouseEventArgs e) { ptStartView = new Point(e.X,e.Y);//Start point ptStart = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptStartView); if( !this.isDrawing) { //start creating lines graph element this.isDrawing = true;//Drawing status ptList.Clear(); ptList.Add(ptStart); ptPreView = ptStartView; } } public override void OnMouseMove(MouseEventArgs e) { if(!this.isDrawing)//Drawing Status=false return; Point ptCurView = new Point(e.X,e.Y);//Temporary end point //Convert the end position to orginal coordinate when you zoom in or zoom out Point ptCur = Canvas.Instance.MainView.ConvertViewToCanvasPt(ptCurView); ptList.Add(ptCur); Pen p = DrawEnvMgr.Instance.Pen; using(Graphics g = Canvas.Instance.MainView.CreateGraphics()) { Rectangle rc = new Rectangle(new Point(0,0),Canvas.Instance.Size); rc = Canvas.Instance.MainView.ConvertCanvasToViewBitmapRect(rc); Region r = new Region(rc); Region old = g.Clip; g.Clip = r; g.DrawLine(p,ptPreView,ptCurView); g.Clip = old; } ptPreView = ptCurView; } public override void OnMouseUp(MouseEventArgs e) { if(this.isDrawing) { this.isDrawing = false;//Drawing status = false Point[] pts = ptList.ToArray(typeof(Point)) as Point[]; FreehandLinesGra linesGra = new FreehandLinesGra(DrawEnvMgr.Instance.Pen,pts); Canvas.Instance.GraList.Add(linesGra); Canvas.Instance.IsModified = true; } } } }