Canvas.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Collections;
  5. using System.ComponentModel;
  6. using System.Windows.Forms;
  7. using System.Data;
  8. using System.Drawing.Imaging;
  9. using System.IO;
  10. using System.Drawing.Printing;
  11. using System.Diagnostics;
  12. using GraEditor.DrawTools;
  13. using GraEditor.Elements;
  14. namespace GraEditor
  15. {
  16. public class Canvas
  17. {
  18. //Construct graList to save the drawing actions
  19. protected Canvas()
  20. {
  21. this.graList = new ArrayList(); // define an arraylist with name gralist for saving all the drawing actions
  22. }
  23. //Initialize the canvas. Set name,size and background color of canvas
  24. public void Init(string name, Size size, Color backColor)
  25. {
  26. this.name = name;//Set name of canvas
  27. this.Size = size;//Set size of canvas
  28. this.backColor = backColor;//Set background color of canvas
  29. this.graList.Clear();//Clear all the elements in graList
  30. //this.mainView.AutoScrollMinSize = this.Size;//this.Size;//Set the size of mainView as canvas size
  31. this.isSavedOnce = false;
  32. this.IsModified = false;
  33. }
  34. private static Canvas _single;
  35. public static Canvas Instance
  36. {
  37. //Get canvas instance
  38. get
  39. {
  40. if (_single == null)
  41. _single = new Canvas();
  42. return _single;
  43. }
  44. }
  45. public event EventHandler Modified;
  46. protected void OnModified()
  47. {
  48. if (Modified != null)
  49. Modified(this, EventArgs.Empty);
  50. }
  51. //Dirty flag
  52. private bool isModified;
  53. public bool IsModified
  54. {
  55. get { return this.isModified; }
  56. set
  57. {
  58. this.isModified = value;
  59. OnModified();
  60. }
  61. }
  62. private bool isSavedOnce;
  63. public bool IsSavedOnce
  64. {
  65. get { return this.isSavedOnce; }
  66. set { this.isSavedOnce = value; }
  67. }
  68. private MainView mainView;//private Mainview variable of canvas
  69. public MainView MainView
  70. {
  71. get { return mainView; }
  72. set { mainView = value; }
  73. }
  74. public void Update()//Refresh canvas
  75. {
  76. this.mainView.UpdateView();
  77. }
  78. private string name;//canvas name
  79. public string Name
  80. {
  81. get { return name; }
  82. set { name = value; }
  83. }
  84. private Size size;//canvas size
  85. public Size Size
  86. {
  87. get { return size; }
  88. set
  89. {
  90. size = value;
  91. this.mainView.AutoScrollMinSize = this.size;//this.Size;//Set the size of mainView as canvas size
  92. }
  93. }
  94. private Color backColor;//canvas color i.e. background color of the image
  95. public Color BackColor
  96. {
  97. get { return backColor; }
  98. set
  99. {
  100. backColor = value;
  101. this.Update();
  102. }
  103. }
  104. private ArrayList graList;//Save drawing action on canvas
  105. public ArrayList GraList
  106. {
  107. get { return graList; }
  108. }
  109. public void AddGra(GraElement gra)
  110. {
  111. this.graList.Add(gra);
  112. this.IsModified = true;
  113. this.Update();
  114. }
  115. public void DelGra(GraElement gra)
  116. {
  117. this.graList.Remove(gra);
  118. this.IsModified = true;
  119. this.Update();
  120. }
  121. //Draw function of canvas
  122. public void Draw(Graphics g)
  123. {
  124. foreach (GraElement gra in graList)//Draw all the element in the graList
  125. gra.Draw(g);
  126. }
  127. public bool Open()
  128. {
  129. OpenFileDialog dlg = new OpenFileDialog(); // new open dialog box is instantiated
  130. dlg.Filter = "位图文件(*.bmp;*.jpg;*.gif;*.png)|*.bmp;*.jpg;*.gif;*.png";
  131. dlg.FilterIndex = 1;
  132. dlg.RestoreDirectory = true;
  133. bool bRtn = false;
  134. if (dlg.ShowDialog() == DialogResult.OK)
  135. {
  136. try
  137. {
  138. bRtn = this.OpenFile(dlg.FileName);
  139. }
  140. catch (Exception ex)
  141. {
  142. MessageBox.Show("文件打开错误 - " + ex.Message);
  143. }
  144. }
  145. return bRtn;
  146. }
  147. private FileStream canvasStream;
  148. public bool OpenFile(string fileName)
  149. {
  150. FileInfo fi = new FileInfo(fileName);
  151. if (!fi.Exists)
  152. {
  153. MessageBox.Show("选择的文不存在!", "Open File");
  154. return false;
  155. }
  156. try
  157. {
  158. canvasStream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
  159. }
  160. catch (Exception ex)
  161. {
  162. MessageBox.Show("文件打开错误 - " + ex.Message);
  163. }
  164. Bitmap bmp = new Bitmap(canvasStream);
  165. //fs.Close();
  166. if (bmp != null)
  167. {
  168. Canvas.Instance.Init(fileName, bmp.Size, Color.White);
  169. ImageGra imageGra = new ImageGra(bmp, new Rectangle(new Point(0, 0), bmp.Size));
  170. Canvas.Instance.GraList.Clear();
  171. Canvas.Instance.GraList.Add(imageGra);//Add to GraList
  172. Canvas.Instance.Update();//Update canvas
  173. CurrentBgImage = new Bitmap(bmp);
  174. }
  175. return true;
  176. }
  177. Bitmap currentBgImage = null;
  178. public Bitmap CurrentBgImage
  179. {
  180. get { return currentBgImage; }
  181. set {
  182. if (currentBgImage != null) {
  183. currentBgImage.Dispose();
  184. }
  185. currentBgImage = value; }
  186. }
  187. /// <summary>
  188. /// 重置 恢复打开时的原始状态
  189. /// </summary>
  190. public void ReloadCanvas()
  191. {
  192. if (currentBgImage != null)
  193. {
  194. Bitmap bmp = new Bitmap(currentBgImage);
  195. ImageGra imageGra = new ImageGra(bmp, new Rectangle(new Point(0, 0), bmp.Size));
  196. Canvas.Instance.GraList.Clear();
  197. Canvas.Instance.GraList.Add(imageGra);//Add to GraList
  198. Canvas.Instance.Update();//Update canvas
  199. }
  200. else {
  201. Canvas.Instance.GraList.Clear();
  202. Canvas.Instance.Update();//Update canvas
  203. }
  204. }
  205. private ImageFormat GetImageFormatByFileName(string fileName)
  206. {
  207. string ext = Path.GetExtension(fileName);
  208. ImageFormat format = ImageFormat.Bmp;
  209. switch (ext)
  210. {
  211. case ".jpg":
  212. format = ImageFormat.Jpeg;
  213. break;
  214. case ".gif":
  215. format = ImageFormat.Gif;
  216. break;
  217. default:
  218. format = ImageFormat.Bmp;
  219. break;
  220. }
  221. return format;
  222. }
  223. /// <summary>
  224. /// 获取新绘制的图片
  225. /// </summary>
  226. /// <returns></returns>
  227. public Bitmap GetNewBitmap()
  228. {
  229. Size s = Canvas.Instance.Size;
  230. Bitmap bmp = new Bitmap(s.Width, s.Height);
  231. Graphics gBmp = Graphics.FromImage(bmp);
  232. gBmp.Clear(Canvas.Instance.BackColor);
  233. this.Draw(gBmp);
  234. return bmp;
  235. }
  236. public void Save()
  237. {
  238. //if(this.canvasStream == null)
  239. // return;
  240. if (this.name == null ||
  241. this.name.Length == 0)
  242. {
  243. MessageBox.Show("文件名无效!", "警告");
  244. return;
  245. }
  246. Bitmap bmp = GetNewBitmap();
  247. try
  248. {
  249. if (this.canvasStream != null)
  250. this.canvasStream.Close();
  251. ImageFormat format = GetImageFormatByFileName(Canvas.Instance.Name);
  252. bmp.Save(Canvas.Instance.Name, format);
  253. bmp.Dispose();
  254. this.IsModified = false;
  255. this.IsSavedOnce = true;
  256. // this.canvasStream = File.Open(this.name, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
  257. }
  258. catch (Exception ex)
  259. {
  260. MessageBox.Show("文件保存错误 - " + ex.Message);
  261. }
  262. }
  263. public bool Close()
  264. {
  265. if (canvasStream != null)
  266. {
  267. canvasStream.Close();
  268. canvasStream = null;
  269. }
  270. return true;
  271. }
  272. }
  273. //Redo & Undo operation
  274. public class GraEditStackMgr
  275. {
  276. private GraEditStackMgr()//construct a redo list
  277. {
  278. this.graRedoList = new ArrayList();
  279. }
  280. private static GraEditStackMgr instance;
  281. public static GraEditStackMgr Instance
  282. {
  283. get
  284. {
  285. if (instance == null)
  286. instance = new GraEditStackMgr();
  287. return instance;
  288. }
  289. }
  290. private ArrayList graRedoList;//Redo list
  291. public ArrayList GraRedoList
  292. {
  293. get { return graRedoList; }
  294. }
  295. public void Clear()
  296. {
  297. this.graRedoList.Clear();
  298. }
  299. //Redo operation
  300. public void Redo()
  301. {
  302. if (this.graRedoList.Count == 0)//no undo happen
  303. return;
  304. int lastIndex = this.graRedoList.Count - 1;//Get the last undo action
  305. //Save last undo action to graLast
  306. GraElement graLast = this.graRedoList[lastIndex] as GraElement;
  307. this.graRedoList.RemoveAt(lastIndex);//Remove the last undo action from redo list
  308. //Canvas.Instance.GraList.Add(graLast);//Save the last undo action to GraList
  309. //Canvas.Instance.Update();//Update canvas
  310. Canvas.Instance.AddGra(graLast);
  311. }
  312. //Undo operation
  313. public void Undo()
  314. {
  315. ArrayList graList = Canvas.Instance.GraList;//Get the GraList of Canvas
  316. if (graList.Count == 0)//No drawing action happen
  317. return;
  318. int lastIndex = graList.Count - 1;//Last drawing action position in graList
  319. //Save the last drawing action to graLast
  320. GraElement graLast = graList[lastIndex] as GraElement;
  321. graList.RemoveAt(lastIndex);//Remove the last drawing action
  322. this.graRedoList.Add(graLast);//Add the last drawing action to redo list
  323. Canvas.Instance.Update();//Update canvas
  324. Canvas.Instance.IsModified = true;
  325. }
  326. }
  327. }