星火微课系统客户端
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

BlackboardNew.cs 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Ink;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. namespace Common.system
  12. {
  13. internal enum ZPenType : byte
  14. {
  15. Pen = 1,
  16. Erase = 2
  17. };
  18. internal class ZBBPage
  19. {
  20. public List<ZBBPageStep> lines { get; set; }
  21. public List<ZBBPageStep> lines_histoty { get; set; }
  22. public ZBBPage()
  23. {
  24. lines = new List<ZBBPageStep>();
  25. lines_histoty = new List<ZBBPageStep>();
  26. }
  27. }
  28. internal class ZBBPageStep
  29. {
  30. public StrokeCollection lines_curr { get; set; }
  31. public StrokeCollection lines_add { get; set; }
  32. public StrokeCollection lines_remove { get; set; }
  33. public ZBBPageStep()
  34. {
  35. lines_curr = new StrokeCollection();
  36. lines_add = new StrokeCollection();
  37. lines_remove = new StrokeCollection();
  38. }
  39. }
  40. public class BlackboardNew
  41. {
  42. private InkCanvas m_canvas;
  43. //private ZPenType type = ZPenType.Pen;
  44. private int pagenum = 0;
  45. private readonly int erasesize = 64;
  46. private readonly int pensize = 3;
  47. private int undoOrRedo = 0; //是否在进行撤销恢复操作
  48. private Color pencolor;
  49. private readonly List<ZBBPage> strokes_page_all = new List<ZBBPage>();
  50. // 添加这个变量是因为在用橡皮擦时 一次操作会触发多次StrokesChanged回掉 这里是把多次回掉合并在一起
  51. private ZBBPageStep step = null;
  52. public BlackboardNew(InkCanvas canvas)
  53. {
  54. init(canvas, Colors.White);
  55. }
  56. public BlackboardNew(InkCanvas canvas, Color _pencolor)
  57. {
  58. init(canvas, _pencolor);
  59. }
  60. private void init(InkCanvas canvas, Color _pencolor)
  61. {
  62. m_canvas = canvas;
  63. pencolor = _pencolor;
  64. ZBBPage page = new ZBBPage();
  65. page.lines.Add(new ZBBPageStep());
  66. strokes_page_all.Add(page);
  67. if (canvas != null)
  68. {
  69. canvas.EditingMode = InkCanvasEditingMode.Ink;
  70. DrawingAttributes drawingAttributes = new DrawingAttributes();
  71. canvas.DefaultDrawingAttributes = drawingAttributes;
  72. drawingAttributes.Width = pensize;
  73. drawingAttributes.Height = pensize;
  74. drawingAttributes.Color = pencolor;
  75. drawingAttributes.FitToCurve = true;
  76. drawingAttributes.IgnorePressure = false;
  77. canvas.Strokes.StrokesChanged += Strokes_StrokesChanged;
  78. canvas.StrokeCollected += Canvas_StrokeCollected;
  79. canvas.StrokeErasing += Canvas_StrokeErasing;
  80. canvas.StrokeErased += Canvas_StrokeErased;
  81. canvas.MouseUp += Canvas_MouseUp;
  82. }
  83. }
  84. private void Canvas_StrokeErasing(object sender, InkCanvasStrokeErasingEventArgs e)
  85. {
  86. undoOrRedo = 0;
  87. }
  88. private void Canvas_StrokeErased(object sender, RoutedEventArgs e)
  89. {
  90. }
  91. private void Canvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
  92. {
  93. }
  94. private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
  95. {
  96. if (step != null)
  97. {
  98. ZBBPage page = strokes_page_all[pagenum];
  99. if (page != null)
  100. {
  101. step.lines_curr.Add(m_canvas.Strokes);
  102. page.lines.Add(step);
  103. step = null;
  104. }
  105. }
  106. }
  107. private void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
  108. {
  109. if (undoOrRedo > 0)
  110. {
  111. undoOrRedo -= 1;
  112. return;
  113. }
  114. if (step == null)
  115. {
  116. step = new ZBBPageStep();
  117. }
  118. // 笔模式
  119. if (e.Added.Count > 0 && e.Removed.Count == 0)
  120. {
  121. step.lines_add.Add(e.Added);
  122. }
  123. // 橡皮模式 会多次进入回掉
  124. else if (e.Removed.Count > 0)
  125. {
  126. step.lines_add.Add(e.Added);
  127. for (int i = 0; i < e.Removed.Count; i++)
  128. {
  129. Stroke removeItem = e.Removed[i];
  130. if (step.lines_add.Contains(removeItem))
  131. {
  132. step.lines_add.Remove(removeItem);
  133. }
  134. else
  135. {
  136. step.lines_remove.Add(removeItem);
  137. }
  138. }
  139. }
  140. }
  141. // public方法 笔
  142. public void change_pen()
  143. {
  144. //this.type = ZPenType.Pen;
  145. DrawingAttributes drawingAttributes = new DrawingAttributes();
  146. m_canvas.DefaultDrawingAttributes = drawingAttributes;
  147. drawingAttributes.Color = pencolor;
  148. drawingAttributes.Width = pensize;
  149. drawingAttributes.Height = pensize;
  150. drawingAttributes.FitToCurve = true;
  151. drawingAttributes.IgnorePressure = false;
  152. m_canvas.EditingMode = InkCanvasEditingMode.Ink;
  153. }
  154. // 橡皮
  155. public void change_erase()
  156. {
  157. //this.type = ZPenType.Erase;
  158. m_canvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
  159. m_canvas.EraserShape = new EllipseStylusShape(erasesize, erasesize, 0);
  160. }
  161. // 撤销
  162. public void undo()
  163. {
  164. ZBBPage page = strokes_page_all[pagenum];
  165. if (page != null && m_canvas.Strokes.Count > 0 && page.lines.Count > 1)
  166. {
  167. ZBBPageStep last = page.lines.Last();
  168. page.lines.Remove(last);
  169. page.lines_histoty.Add(last);
  170. if (page.lines.Last().lines_curr.Count > 0)
  171. {
  172. undoOrRedo = 2;
  173. }
  174. else
  175. {
  176. undoOrRedo = 1;
  177. }
  178. m_canvas.Strokes.Clear();
  179. m_canvas.Strokes.Add(page.lines.Last().lines_curr);
  180. }
  181. }
  182. // 恢复
  183. public void redo()
  184. {
  185. ZBBPage page = strokes_page_all[pagenum];
  186. if (page != null && page.lines_histoty.Count > 0)
  187. {
  188. ZBBPageStep line = page.lines_histoty[page.lines_histoty.Count - 1];
  189. page.lines.Add(line);
  190. page.lines_histoty.Remove(line);
  191. if (page.lines.Last().lines_curr.Count > 0)
  192. {
  193. undoOrRedo = 2;
  194. }
  195. else
  196. {
  197. undoOrRedo = 1;
  198. }
  199. m_canvas.Strokes.Clear();
  200. m_canvas.Strokes.Add(page.lines.Last().lines_curr);
  201. }
  202. }
  203. // 清空
  204. public void clear()
  205. {
  206. ZBBPage page = strokes_page_all[pagenum];
  207. if (page != null)
  208. {
  209. m_canvas.Strokes.Clear();
  210. page.lines_histoty.Clear();
  211. page.lines.Clear();
  212. page.lines.Add(new ZBBPageStep());
  213. }
  214. }
  215. public void changepage(int mpagenum)
  216. {
  217. if (pagenum != mpagenum)
  218. {
  219. pagenum = mpagenum;
  220. if (pagenum >= strokes_page_all.Count)
  221. {
  222. int numadd = pagenum - strokes_page_all.Count + 1;
  223. for (int i = 0; i < numadd; i++)
  224. {
  225. ZBBPage pagetemp = new ZBBPage();
  226. pagetemp.lines.Add(new ZBBPageStep());
  227. strokes_page_all.Add(pagetemp);
  228. }
  229. }
  230. ZBBPage page = strokes_page_all[pagenum];
  231. if (page != null)
  232. {
  233. if (page.lines.Last().lines_curr.Count > 0)
  234. {
  235. undoOrRedo += 1;
  236. }
  237. if (m_canvas.Strokes.Count > 0)
  238. {
  239. undoOrRedo += 1;
  240. m_canvas.Strokes.Clear();
  241. }
  242. m_canvas.Strokes.Add(page.lines.Last().lines_curr);
  243. }
  244. }
  245. }
  246. }
  247. }