My Project
C:/Users/Lab_411_02/Desktop/Violet1 - dox/violet/violet/GraphDoc.cs
查看本檔案說明文件.
1 using ShapeLib.VShape;
2 //using Microsoft.Office.Interop.Word;
3 //using Microsoft.Office.Tools.Word;
4 using System;
5 using System.Collections;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Linq;
9 using System.Text;
10 using System.Threading.Tasks;
11 using System.Windows;
12 using System.Windows.Input;
13 using System.Windows.Media;
14 using System.Windows.Shapes;
15 using System.Xml.Serialization;
16 
17 
18 namespace ShapeLib.VShape
19 {
20 
21  [XmlRoot(ElementName = "SVGRoot", Namespace = "")]
22  public class SVGRoot
23  {
24  [XmlElement("PathList")]
25  public List<gPath> PathList = new List<gPath>();
26  }
32  public class GraphDoc
33  {
34  public SVGRoot sroot = new SVGRoot();
35  public List<gView> shapeList = new List<gView>();
36  public List<gPath> FullList = new List<gPath>(); //remember all action from grid
37  public Stack UndoStack = new Stack();
38  public Stack RedoStack = new Stack();
39  public int selIndex = -1; // The last seat in PathList array
40  public int node = 0;
41  public int mx;
42  public int my;
43  public bool bmove;
44 
45  public int checkWhich(gPath gp)
46  {
47  int whichOne = -1;
48  for (int i = sroot.PathList.Count - 1; i >= 0; i--)
49  {
50  if (gp.drawtype < 3 || gp.drawtype == 4)
51  {
52  if (sroot.PathList[i].controlBtn1 != gp.controlBtn1)
53  continue;
54  if (sroot.PathList[i].controlBtn2 != gp.controlBtn2)
55  continue;
56  if (sroot.PathList[i].controlBtn3 != gp.controlBtn3)
57  continue;
58  if (sroot.PathList[i].controlBtn4 != gp.controlBtn4)
59  continue;
60  }
61  if (gp.drawtype == 3)
62  {
63  if (sroot.PathList[i].controlBtn1 != gp.controlBtn1)
64  continue;
65  if (sroot.PathList[i].controlBtn4 != gp.controlBtn4)
66  continue;
67  }
68  whichOne = i;
69  }
70  return whichOne;
71  }
72 
73  public void reDrawAll()
74  {
75  foreach (gPath gp in sroot.PathList)
76  {
77  if (!gp.IsDelete)
78  {
79  gp.redraw(1);
80 
81  }
82  }
83 
84  }
85 
91  public void writeIn(gPath Data, int Action)
92  {
93 
94 
95  saveState pa;
96 
97  int lens = RedoStack.Count;
98  RedoStack.Clear();
99  FullList.RemoveRange(FullList.Count - lens, lens);
100 
101 
102 
103  if (Action == 0)//新增動作
104  {
105  gPath g = new gPath();
106  //等一下會加入到list 中,所以count 正好為其在list 所在的位置
107  pa = new saveState(Action, sroot.PathList.Count, (FullList.Count));
108 
109  UndoStack.Push(pa);
110  g.copyVal(Data);
111  FullList.Add(Data);
112  sroot.PathList.Add(g);
113  }
114  else //修改動作(物件已存在)
115  {
116  pa = new saveState(Action, Data.ListPlace, FullList.Count);
117  FullList.Add(Data);
118  UndoStack.Push(pa);
119  }
120  }
121 
122 
127  public void reDo()
128  {
129  if (RedoStack.Count > 0)
130  {
131  gPath tempPath = new gPath();
132  saveState tempPA;
133 
134  tempPA = (saveState)RedoStack.Pop();
135 
136  if (tempPA.currSate >= 0 && tempPA.currSate < FullList.Count)
137  {
138  tempPath.copyVal(FullList[tempPA.currSate]);
139 
140 
141  if (tempPA.Action == 0)
142  sroot.PathList[tempPA.GraphIndex].IsDelete = false;
143 
144  sroot.PathList[tempPA.GraphIndex] = tempPath;
145  sroot.PathList[tempPA.GraphIndex].redraw(1);
146 
147  }
148  else
149  {
150  // sroot.PathList.RemoveAt(tempPA.GraphIndex);
151  }
152  UndoStack.Push(tempPA);
153 
154  }
155  }
156 
160  public void unDo()
161  {
162  //檢查是否有可undo 的事件
163  if (UndoStack.Count > 0)
164  {
165  gPath tempPath = new gPath();
166  saveState tempPA;
167  shapeLib.Data.mClick = 0;
168 
169  tempPA = (saveState)UndoStack.Pop();
170 
171  if (tempPA.currSate >= 0 && tempPA.currSate < FullList.Count)
172  {
173  if (tempPA.Action == 0)
174  {
175 
176  sroot.PathList[tempPA.GraphIndex].IsDelete = true;
177 
178  }
179  else
180  {
181  //找出前一個state
182  int i;
183  for (i = tempPA.currSate - 1; i >= 0; i--)
184  {
185  if (FullList[i].ListPlace == tempPA.GraphIndex)
186  {
187  tempPath.copyVal(FullList[i]);
188  sroot.PathList[tempPA.GraphIndex] = tempPath;
189  sroot.PathList[tempPA.GraphIndex].redraw(1);
190  break;
191 
192  }
193  }
194  if (i < 0) //something wrong
195  {
196  Debug.WriteLine("something wrong");
197  }
198 
199  }
200 
201  }
202  else
203  {
204 
205  //something wrong
206  Debug.WriteLine("something wrong");
207 
208  //sroot.PathList.RemoveAt(tempPA.GraphIndex);
209  }
210  //將該事件放入redo stack
211  RedoStack.Push(tempPA);
212 
213  }
214  }
215 
216  public void Release()
217  {
218  this.RedoStack.Clear();
219  }
220  }
221 
222  [Serializable]
223  public struct gPro
224  {
225  public byte colorR;
226  public byte colorG;
227  public byte colorB;
228  public int strokeT;
229  }
230  [Serializable]
231  public class gPath
232  {
233  public int drawtype;
234  public gPro state;
235  public int ListPlace;
236  public System.Windows.Point controlBtn1;
237  public System.Windows.Point controlBtn2;
238  public System.Windows.Point controlBtn3;
239  public System.Windows.Point controlBtn4;
240  public String Text = "";
241  bool _isSel;
242  public List<Point> pList = new List<Point>();
243  public bool isSel
244  {
245  get
246  {
247  return _isSel;
248  }
249  set
250  {
251 
252  if (value != _isSel)
253  {
254  _isSel = value;
255  if (!value)
256  redraw(2);
257  else
258  redraw(1);
259  }
260 
261  }
262  }
263  private int shapeIndex = -1;
264 
269  public void redraw(int removetype)
270  {
271  gView gv = null;
272  Boolean bfirst = false;
273 
274  if (shapeIndex < 0)
275  {
276  gv = new gView();
278  shapeLib.Data.gdc.shapeList.Add(gv);
279  bfirst = true;
280  }
281  else
283 
284 
285  if (isSel)
286  {
287  foreach (Shape sp in gv.baseShape)
288  shapeLib.Data.mygrid.Children.Remove(sp);
289  shapeLib.SupportedShape(null)[drawtype].DisplayControlPoints(gv, this);
290 
291  }
292  else
293  {
294  foreach (Shape sp in gv.controlShape)
295  shapeLib.Data.mygrid.Children.Remove(sp);
296  gv.controlShape.Clear();
297 
298  switch (removetype)
299  {
300  case -1:
301  foreach (Shape sp in gv.baseShape)
302  shapeLib.Data.mygrid.Children.Remove(sp);
303  break;
304 
305 
306  case 2:
307  foreach (Shape sp in gv.baseShape)
308  shapeLib.Data.mygrid.Children.Add(sp);
309  shapeLib.SupportedShape(null)[drawtype].DrawShape(gv, this, bfirst);
310  break;
311  case 0:
312  case 1:
313  shapeLib.SupportedShape(null)[drawtype].DrawShape(gv, this, bfirst);
314 
315  break;
316 
317  }
318  }
319  }
320 
321  // public Shape getDrawShape()
322  // {
323  // if (shapeIndex >= 0 && shapeIndex < shapeLib.Data.gdc.shapeList.Count)
324  // {
325  // Shape ishape = shapeLib.Data.gdc.shapeList[shapeIndex];
326  // return ishape;
327  // }
328  // return null;
329 
330  // }
331 
332  //public void setDrawShape(Shape value)
333  // {
334  // shapeLib.Data.gdc.shapeList.Add(value);
335  // shapeIndex = shapeLib.Data.gdc.shapeList.Count - 1;
336  // }
337 
338 
339  private bool isdel = false;
340  public bool IsDelete
341  {
342  get
343  {
344 
345 
346  return isdel;
347  //throw new NotImplementedException();
348  }
349  set
350  {
351  if (value == true)
352  {
353  this.redraw(-1);
354 
355 
356 
357  }
358  else
359  {
360  if (isdel)
361  {
362  this.redraw(2);
363 
364 
365  }
366 
367 
368  }
369  isdel = true;
370 
371 
372  // throw new NotImplementedException();
373  }
374  }
375  public void myLine_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
376  {
377  if (shapeLib.Data.UItype < 0)
378  {
379  if (isSel)
380  {
381  double gapX, gapY, x, y;
382  shapeLib.Data.mygrid.Cursor = Cursors.SizeAll;
383  gapX = Math.Abs(shapeLib.Data.currShape.controlBtn4.X + shapeLib.Data.currShape.controlBtn1.X) / 2.0;
384  gapY = Math.Abs(shapeLib.Data.currShape.controlBtn4.Y + shapeLib.Data.currShape.controlBtn1.Y) / 2.0;
385  x = e.GetPosition(shapeLib.Data.mygrid).X;
386  y = e.GetPosition(shapeLib.Data.mygrid).Y;
395  //if (this.Equals(typeof(ShapeRectangle)))
396  //{
397  // this.controlBtn1 = e.GetPosition(shapeLib.Data.mygrid);
398  //}
399  }
400  else
401  {
402  shapeLib.Data.mygrid.Cursor = Cursors.Hand;
403 
404  }
405 
406  }
407  // throw new NotImplementedException();
408  }
409 
410  public void myLine_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
411  {
412  shapeLib.Data.mygrid.Cursor = Cursors.Arrow;
413 
414  // throw new NotImplementedException();
415  }
416 
417 
418  public void myLine_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
419  {
420  if (shapeLib.Data.UItype < 0)
421  {
422  //檢查是否有按下shift
423  if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
424  {
425  shapeLib.Data.multiSelList.Add(this);
426 
427  }
428  else
429  {
430  foreach (gPath gp in shapeLib.Data.multiSelList)
431  {
432  gp.isSel = false;
433  }
434  if (shapeLib.Data.currShape != null && shapeLib.Data.currShape != this)
435  shapeLib.Data.currShape.isSel = false;
436  shapeLib.Data.multiSelList.Clear();
437  shapeLib.Data.multiSelList.Add(this);
438  }
439 
440  shapeLib.Data.currShape = this;
441  this.isSel = true;
442 
443  IInsertOP sh = shapeLib.SupportedShape(null)[this.drawtype];
444  sh.MouseOP(1);
445 
446  e.Handled = true;
447  }
448  //throw new NotImplementedException();
449  }
450 
451 
452  public void copyVal(gPath obj)
453  {
454 
455  drawtype = obj.drawtype;
456  state = obj.state;
457  ListPlace = obj.ListPlace;
458  shapeIndex = obj.shapeIndex;
459 
460  controlBtn1 = obj.controlBtn1;
461  controlBtn2 = obj.controlBtn2;
462  controlBtn3 = obj.controlBtn3;
463  controlBtn4 = obj.controlBtn4;
464 
465  foreach (Point p in obj.pList)
466  {
467  pList.Add(p);
468  }
469  }
470 
471  }
472 
473  public class RUse
474  {
475  public int Sel = -1;
476  public int Node = -1;
477  public System.Windows.Point Point;
478  }
479 
480  public class gPoint
481  {
482  public System.Windows.Point mouseXY;
483 
484  public System.Windows.Point point0;
485  public System.Windows.Point point1;
486  public System.Windows.Point point2;
487  public System.Windows.Point point3;
488  }
492  public class saveState
493  {
494  //0: insert, 1:update, 2:delete
495  public int Action;
496  //目前圖形串列中的第幾個,為必免順序改變,凡加入的就一直存在(data list)
497  public int GraphIndex;
498 
499  //操作前的狀態 fullList 中,操作前該物件所在位置,即最後一個狀態.至少會有新增的狀態.以GraphIndex 去找,其實可以不用記錄
500  //int preSate;
501 
502  //操作後的狀態 fullList 中,剛更改的狀態
503  public int currSate;
504 
505 
506 
507  public saveState()
508  {
509  Action = -1;
510  GraphIndex = -1;
511  currSate = -1;
512  //changeP = 0;
513  //lastP = -1;
514  //leastP = 0;
515 
516  }
517  public saveState(int a, int b, int c)
518  {
519  Action = a;
520  GraphIndex = b;
521  currSate = c;
522  }
523 
524  }
525 
526  public class checkHitDraw
527  {
528  public int checkHitWhich(List<gPath> l, gPoint gp, int drawType)
529  {
530  int whichOne = -1;
531  for (int i = l.Count - 1; i >= 0; i--)
532  {
533  if (drawType < 3 || drawType == 4)
534  {
535  if (l[i].controlBtn1 != gp.point0)
536  continue;
537  if (l[i].controlBtn2 != gp.point1)
538  continue;
539  if (l[i].controlBtn3 != gp.point2)
540  continue;
541  if (l[i].controlBtn4 != gp.point3)
542  continue;
543  }
544  if (drawType == 3)
545  {
546  if (l[i].drawtype != drawType)
547  continue;
548  if (l[i].controlBtn1 != gp.point0)
549  continue;
550  if (l[i].controlBtn4 != gp.point3)
551  continue;
552  }
553  whichOne = i;
554  }
555  return whichOne;
556  }
557 
558  public bool checkHitEllipse(gPoint p)
559  {
560  bool tf = false;
561  double c_x = (p.point1.X - p.point0.X) / 2;
562  double c_y = (p.point2.Y - p.point0.Y) / 2;
563  System.Windows.Point center = new System.Windows.Point(p.point0.X + c_x, p.point0.Y + c_y);
564 
565  double simpleX = Math.Sqrt((1 - Math.Pow((p.mouseXY.Y - center.Y), 2) / Math.Pow(c_y, 2)) * Math.Pow(c_x, 2));
566  double simpleY = Math.Sqrt((1 - Math.Pow((p.mouseXY.X - center.X), 2) / Math.Pow(c_x, 2)) * Math.Pow(c_y, 2));
567  double higherPlaceX = center.X + simpleX;
568  double lowerPlaceX = center.X - simpleX;
569  double higherPlaceY = center.Y + simpleY;
570  double lowerPlaceY = center.Y - simpleY;
571 
572  if (p.mouseXY.X <= higherPlaceX && p.mouseXY.X >= higherPlaceX - 3)
573  tf = true;
574  if (p.mouseXY.X >= lowerPlaceX && p.mouseXY.X <= lowerPlaceX + 3)
575  tf = true;
576  if (p.mouseXY.Y <= higherPlaceY && p.mouseXY.Y >= higherPlaceY - 3)
577  tf = true;
578  if (p.mouseXY.Y >= lowerPlaceY && p.mouseXY.Y <= lowerPlaceY + 3)
579  tf = true;
580 
581  return tf;
582  }
583 
584  public bool checkHitRect(gPoint p)
585  {
586  bool tf = false;
587  if ((p.mouseXY.X <= p.point1.X + 3 && p.mouseXY.X >= p.point1.X - 3) || (p.mouseXY.X >= p.point0.X - 3 && p.mouseXY.X <= p.point0.X + 3))
588  {
589  if (p.mouseXY.Y <= p.point2.Y && p.mouseXY.Y >= p.point0.Y)
590  {
591  tf = true;
592  }
593  }
594  if ((p.mouseXY.Y <= p.point2.Y + 3 && p.mouseXY.Y >= p.point2.Y - 3) || (p.mouseXY.Y >= p.point0.Y - 3 && p.mouseXY.Y <= p.point0.Y + 3))
595  {
596  if (p.mouseXY.X <= p.point1.X && p.mouseXY.X >= p.point0.X)
597  {
598  tf = true;
599  }
600  }
601  return tf;
602  }
603 
604  public bool checkHitLine(System.Windows.Point downPlace, gPath p)
605  {
606  bool tf = false;
607  double m = (p.controlBtn4.Y - p.controlBtn1.Y) / (p.controlBtn4.X - p.controlBtn1.X);
608  double xm = (downPlace.Y - p.controlBtn1.Y) / m + p.controlBtn1.X;
609  double ym = (downPlace.X - p.controlBtn1.X) * m + p.controlBtn1.Y;
610  if (downPlace.X >= xm - 3 && downPlace.X <= xm + 3)
611  tf = true;
612  if (downPlace.Y >= ym - 3 && downPlace.Y <= ym + 3)
613  tf = true;
614  return tf;
615  }
616 
617  public bool checkHitCurve(String Data, gPath p)
618  {
619  bool tf = true;
620  String[] tmpStr = Data.Split(',');
621  double[] tmpDouStr = new double[tmpStr.Length];
622  for (int i = 0; i < tmpStr.Length; i++)
623  {
624  tmpDouStr[i] = Convert.ToDouble(tmpStr[i]);
625  }
626  System.Windows.Point tmpPoint0 = new System.Windows.Point(tmpDouStr[0], tmpDouStr[1]);
627  System.Windows.Point tmpPoint1 = new System.Windows.Point(tmpDouStr[2], tmpDouStr[3]);
628  System.Windows.Point tmpPoint2 = new System.Windows.Point(tmpDouStr[4], tmpDouStr[5]);
629  System.Windows.Point tmpPoint3 = new System.Windows.Point(tmpDouStr[6], tmpDouStr[7]);
630 
631  if (!tmpPoint0.Equals(p.controlBtn1))
632  tf = false;
633  if (!tmpPoint1.Equals(p.controlBtn2))
634  tf = false;
635  if (!tmpPoint2.Equals(p.controlBtn3))
636  tf = false;
637  if (!tmpPoint3.Equals(p.controlBtn4))
638  tf = false;
639  return tf;
640  }
641 
642  public int checkHitCorner(System.Windows.Point downPlace, gPath p)
643  {
644  int Node = -1;
645  if ((downPlace.X >= p.controlBtn1.X - 4) && (downPlace.X <= p.controlBtn1.X + 4) && (downPlace.Y >= p.controlBtn1.Y - 4) && (downPlace.Y <= p.controlBtn1.Y + 4))
646  {
647  Node = 0;
648  }
649  if ((downPlace.X >= p.controlBtn2.X - 4) && (downPlace.X <= p.controlBtn2.X + 4) && (downPlace.Y >= p.controlBtn2.Y - 4) && (downPlace.Y <= p.controlBtn2.Y + 4))
650  {
651  Node = 1;
652  }
653  if ((downPlace.X >= p.controlBtn3.X - 4) && (downPlace.X <= p.controlBtn3.X + 4) && (downPlace.Y >= p.controlBtn3.Y - 4) && (downPlace.Y <= p.controlBtn3.Y + 4))
654  {
655  Node = 2;
656  }
657  if ((downPlace.X >= p.controlBtn4.X - 4) && (downPlace.X <= p.controlBtn4.X + 4) && (downPlace.Y >= p.controlBtn4.Y - 4) && (downPlace.Y <= p.controlBtn4.Y + 4))
658  {
659  Node = 3;
660  }
661  return Node;
662  }
663 
664  public bool checkHitCenter(System.Windows.Point downPlace, gPath p)
665  {
666  bool tf = true;
667  if (downPlace.X > p.controlBtn2.X || downPlace.X < p.controlBtn1.X)
668  tf = false;
669  if (downPlace.Y > p.controlBtn4.Y || downPlace.Y < p.controlBtn1.Y)
670  tf = false;
671  return tf;
672  }
673  }
674 
675 }
static GModel Data
Definition: shapeLib.cs:42
System.Windows.Point point3
Definition: GraphDoc.cs:506
List< gPath > FullList
Definition: GraphDoc.cs:41
List< gPath > multiSelList
Definition: shapeLib.cs:148
System.Windows.Point controlBtn3
Definition: GraphDoc.cs:255
List< gPath > PathList
Definition: GraphDoc.cs:30
bool checkHitCenter(System.Windows.Point downPlace, gPath p)
Definition: GraphDoc.cs:664
int checkHitWhich(List< gPath > l, gPoint gp, int drawType)
Definition: GraphDoc.cs:528
System.Windows.Point Point
Definition: GraphDoc.cs:496
List< gView > shapeList
Definition: GraphDoc.cs:40
System.Windows.Point point1
Definition: GraphDoc.cs:504
System.Windows.Point point0
Definition: GraphDoc.cs:503
System.Windows.Point point2
Definition: GraphDoc.cs:505
void writeIn(gPath Data, int Action)
維護 undo stack ,把目前狀態存起來.並清空redo stack,如果之前有undo 動作,是回覆到某一狀態,在此之後的動作都可清除
Definition: GraphDoc.cs:91
System.Windows.Point controlBtn4
Definition: GraphDoc.cs:256
bool checkHitLine(System.Windows.Point downPlace, gPath p)
Definition: GraphDoc.cs:604
void myLine_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
Definition: GraphDoc.cs:375
System.Windows.Point controlBtn2
Definition: GraphDoc.cs:254
int Action
0: insert, 1:update, 2:delete
Definition: GraphDoc.cs:516
void myLine_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
Definition: GraphDoc.cs:410
為了維護undo redo, 系統任何操作必需把狀態存起來,
Definition: GraphDoc.cs:511
void redraw(int removetype)
Definition: GraphDoc.cs:286
int GraphIndex
目前圖形串列中的第幾個,為必免順序改變,凡加入的就一直存在(data list)
Definition: GraphDoc.cs:520
記錄shape list,action data stack 記錄動作,每個動作(pointAry)包含,該圖是圖形的第幾個(Listplace),之前記錄是否己有相同圖是第幾個,...
Definition: GraphDoc.cs:37
System.Windows.Point mouseXY
Definition: GraphDoc.cs:501
static IList< ShapeObj > SupportedShape(getForm myview)
define supported shape
Definition: shapeLib.cs:27
bool checkHitCurve(String Data, gPath p)
Definition: GraphDoc.cs:617
void MouseOP(int ntype)
List< Point > pList
Definition: GraphDoc.cs:259
List< Shape > baseShape
Definition: gView.cs:12
void copyVal(gPath obj)
Definition: GraphDoc.cs:471
System.Windows.Point controlBtn1
Definition: GraphDoc.cs:253
bool checkHitEllipse(gPoint p)
Definition: GraphDoc.cs:558
void unDo()
undo 回到前一狀態
Definition: GraphDoc.cs:160
bool checkHitRect(gPoint p)
Definition: GraphDoc.cs:584
void myLine_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
Definition: GraphDoc.cs:418
saveState(int a, int b, int c)
Definition: GraphDoc.cs:517
int checkWhich(gPath gp)
Definition: GraphDoc.cs:45
int checkHitCorner(System.Windows.Point downPlace, gPath p)
Definition: GraphDoc.cs:642
void reDo()
重作到目前狀態
Definition: GraphDoc.cs:127
List< Shape > controlShape
Definition: gView.cs:13
int currSate
操作前的狀態 fullList 中,操作前該物件所在位置,即最後一個狀態.至少會有新增的狀態.以GraphIndex 去找,其實可以不用記錄
Definition: GraphDoc.cs:530