GraphDoc
GraphDoc
using ShapeLib.VShape;
//using Microsoft.Office.Interop.Word;
//using Microsoft.Office.Tools.Word;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks; /*允許空間使用類別*/
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Xml.Serialization; /*允許空間檔案序列化*/
namespace ShapeLib.VShape/*宣告範圍*/
{
[XmlRoot(ElementName = "SVGRoot", Namespace = "")]
public class SVGRoot
{
[XmlElement("PathList")]
public List<gPath> PathList = new List<gPath>();
}
/// <summary>
/// 記錄shape list,action data
/// stack 記錄動作,每個動作(pointAry)包含,該圖是圖形的第幾個(Listplace),之前記錄是否己有相同圖是第幾個,目前圖存在記錄的第幾個
///
/// </summary>
public class GraphDoc
{
public SVGRoot sroot = new SVGRoot();
public List<gView> shapeList = new List<gView>();
public List<gPath> FullList = new List<gPath>(); //remember all action from grid
public Stack UndoStack = new Stack();
public Stack RedoStack = new Stack();
public int selIndex = -1; // The last seat in PathList array
public int node = 0;
public int mx;
public int my;
public bool bmove;
public int checkWhich(gPath gp)
{
int whichOne = -1;
for (int i = sroot.PathList.Count - 1; i >= 0; i--)
{
if (gp.drawtype < 3 || gp.drawtype == 4)
{
if (sroot.PathList[i].controlBtn1 != gp.controlBtn1)
continue;
if (sroot.PathList[i].controlBtn2 != gp.controlBtn2)
continue;
if (sroot.PathList[i].controlBtn3 != gp.controlBtn3)
continue;
if (sroot.PathList[i].controlBtn4 != gp.controlBtn4)
continue;
}
if (gp.drawtype == 3)
{
if (sroot.PathList[i].controlBtn1 != gp.controlBtn1)
continue;
if (sroot.PathList[i].controlBtn4 != gp.controlBtn4)
continue;
}
whichOne = i;
}
return whichOne;
}
public void reDrawAll()
{
foreach (gPath gp in sroot.PathList)
{
if (!gp.IsDelete)
{
gp.redraw(1);
}
}
}
/// <summary>
/// 維護 undo stack ,把目前狀態存起來.並清空redo stack,如果之前有undo 動作,是回覆到某一狀態,在此之後的動作都可清除
/// </summary>
/// <param name="Data"></param>
/// <param name="Action"></param>
public void writeIn(gPath Data, int Action)
{
saveState pa;
int lens = RedoStack.Count;
RedoStack.Clear();
FullList.RemoveRange(FullList.Count - lens, lens);// FullList移除項目範圍
if (Action == 0)//新增動作
{
gPath g = new gPath();
//等一下會加入到list 中,所以count 正好為其在list 所在的位置
pa = new saveState(Action, sroot.PathList.Count, (FullList.Count));
UndoStack.Push(pa);
g.copyVal(Data);
FullList.Add(Data);
sroot.PathList.Add(g);
}
else //修改動作(物件已存在)
{
pa = new saveState(Action, Data.ListPlace, FullList.Count);
FullList.Add(Data);
UndoStack.Push(pa);
}
}
/// <summary>
/// 重作到目前狀態
///
/// </summary>
public void reDo()
{
if (RedoStack.Count > 0)
{
gPath tempPath = new gPath();
saveState tempPA;
tempPA = (saveState)RedoStack.Pop();
if (tempPA.currSate >= 0 && tempPA.currSate < FullList.Count)
{
tempPath.copyVal(FullList[tempPA.currSate]);
if (tempPA.Action == 0)
sroot.PathList[tempPA.GraphIndex].IsDelete = false;
sroot.PathList[tempPA.GraphIndex] = tempPath;
sroot.PathList[tempPA.GraphIndex].redraw(1);
}
else
{
// sroot.PathList.RemoveAt(tempPA.GraphIndex);
}
UndoStack.Push(tempPA);
}
}
/// <summary>
/// undo 回到前一狀態
/// </summary>
public void unDo()
{
//檢查是否有可undo 的事件
if (UndoStack.Count > 0)
{
gPath tempPath = new gPath();
saveState tempPA;
shapeLib.Data.mClick = 0;
tempPA = (saveState)UndoStack.Pop();
if (tempPA.currSate >= 0 && tempPA.currSate < FullList.Count)
{
if (tempPA.Action == 0)
{
sroot.PathList[tempPA.GraphIndex].IsDelete = true;
}
else
{
//找出前一個state
int i;
for (i = tempPA.currSate - 1; i >= 0; i--)
{
if (FullList[i].ListPlace == tempPA.GraphIndex)
{
tempPath.copyVal(FullList[i]);
sroot.PathList[tempPA.GraphIndex] = tempPath;
sroot.PathList[tempPA.GraphIndex].redraw(1);
break;
}
}
if (i < 0) //將"something wrong"寫入Debug輸出資料流
{
Debug.WriteLine("something wrong");
}
}
}
else
{
//將"something wrong"寫入Debug輸出資料
Debug.WriteLine("something wrong");
//sroot.PathList.RemoveAt(tempPA.GraphIndex);
}
//將該事件放入redo stack
RedoStack.Push(tempPA);
}
}
public void Release()
{
this.RedoStack.Clear();
}
}
[Serializable]
public struct gPro
{
public byte colorR;
public byte colorG;
public byte colorB;
public int strokeT;
}
[Serializable]
public class gPath
{
public int drawtype;
public gPro state;
public int ListPlace;
public System.Windows.Point controlBtn1;
public System.Windows.Point controlBtn2;
public System.Windows.Point controlBtn3;
public System.Windows.Point controlBtn4;
public String Text = "";
bool _isSel;
public List<Point> pList = new List<Point>();
public bool isSel
{
get
{
return _isSel;
}
set
{
if (value != _isSel)
{
_isSel = value;
if (!value)
redraw(2);
else
redraw(1);
}
}
}
private int shapeIndex = -1;
/// <summary>
///
/// </summary>
/// <param name="remove"> -1 : 移除, 0: 運動中畫, 1: 正式畫 , 2: 重新加入</param>
public void redraw(int removetype)
{
gView gv = null;
Boolean bfirst = false;
if (shapeIndex < 0)
{
gv = new gView();
shapeIndex = shapeLib.Data.gdc.shapeList.Count;
shapeLib.Data.gdc.shapeList.Add(gv);
bfirst = true;
}
else
gv = shapeLib.Data.gdc.shapeList[shapeIndex];
if (isSel)
{
foreach (Shape sp in gv.baseShape)
shapeLib.Data.mygrid.Children.Remove(sp);
shapeLib.SupportedShape(null)[drawtype].DisplayControlPoints(gv, this);
}
else
{
foreach (Shape sp in gv.controlShape)
shapeLib.Data.mygrid.Children.Remove(sp);
gv.controlShape.Clear();
switch (removetype)
{
case -1:
foreach (Shape sp in gv.baseShape)
shapeLib.Data.mygrid.Children.Remove(sp);
break;
case 2:
foreach (Shape sp in gv.baseShape)
shapeLib.Data.mygrid.Children.Add(sp);
shapeLib.SupportedShape(null)[drawtype].DrawShape(gv, this, bfirst);
break;
case 0:
case 1:
shapeLib.SupportedShape(null)[drawtype].DrawShape(gv, this, bfirst);
break;
}
}
}
// public Shape getDrawShape()
// {
// if (shapeIndex >= 0 && shapeIndex < shapeLib.Data.gdc.shapeList.Count)
// {
// Shape ishape = shapeLib.Data.gdc.shapeList[shapeIndex];
// return ishape;
// }
// return null;
// }
//public void setDrawShape(Shape value)
// {
// shapeLib.Data.gdc.shapeList.Add(value);
// shapeIndex = shapeLib.Data.gdc.shapeList.Count - 1;
// }
private bool isdel = false;
public bool IsDelete
{
get
{
return isdel;
//throw new NotImplementedException();
//不實作時擲回的例外狀況
}
set
{
if (value == true)
{
this.redraw(-1);
}
else
{
if (isdel)
{
this.redraw(2);
}
}
isdel = true;
// throw new NotImplementedException();
//不實作時擲回的例外狀況
}
}
public void myLine_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
if (shapeLib.Data.UItype < 0)
{
if (isSel)
{
double gapX, gapY, x, y;
shapeLib.Data.mygrid.Cursor = Cursors.SizeAll;
gapX = Math.Abs(shapeLib.Data.currShape.controlBtn4.X + shapeLib.Data.currShape.controlBtn1.X) / 2.0;
gapY = Math.Abs(shapeLib.Data.currShape.controlBtn4.Y + shapeLib.Data.currShape.controlBtn1.Y) / 2.0;
x = e.GetPosition(shapeLib.Data.mygrid).X;
y = e.GetPosition(shapeLib.Data.mygrid).Y;
shapeLib.Data.currShape.controlBtn4.X = shapeLib.Data.currShape.controlBtn4.X + (x - gapX);
shapeLib.Data.currShape.controlBtn4.Y = shapeLib.Data.currShape.controlBtn4.Y + (y - gapY);
shapeLib.Data.currShape.controlBtn1.X = shapeLib.Data.currShape.controlBtn1.X + (x - gapX);
shapeLib.Data.currShape.controlBtn1.Y = shapeLib.Data.currShape.controlBtn1.Y + (y - gapY);
shapeLib.Data.currShape.controlBtn2.X = shapeLib.Data.currShape.controlBtn2.X + (x - gapX);
shapeLib.Data.currShape.controlBtn2.Y = shapeLib.Data.currShape.controlBtn2.Y + (y - gapY);
shapeLib.Data.currShape.controlBtn3.X = shapeLib.Data.currShape.controlBtn3.X + (x - gapX);
shapeLib.Data.currShape.controlBtn3.Y = shapeLib.Data.currShape.controlBtn3.Y + (y - gapY);
//if (this.Equals(typeof(ShapeRectangle)))
//{
// this.controlBtn1 = e.GetPosition(shapeLib.Data.mygrid);
//}
}
else
{
shapeLib.Data.mygrid.Cursor = Cursors.Hand;
}
}
// throw new NotImplementedException();
}
public void myLine_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
shapeLib.Data.mygrid.Cursor = Cursors.Arrow;
// throw new NotImplementedException();
}
public void myLine_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) //滑鼠左鍵點擊事件
{
if (shapeLib.Data.UItype < 0)
{
//檢查是否有按下shift
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
{
shapeLib.Data.multiSelList.Add(this);
}
else
{
foreach (gPath gp in shapeLib.Data.multiSelList)
{
gp.isSel = false;
}
if (shapeLib.Data.currShape != null && shapeLib.Data.currShape != this)
shapeLib.Data.currShape.isSel = false;
shapeLib.Data.multiSelList.Clear();
shapeLib.Data.multiSelList.Add(this);
}
shapeLib.Data.currShape = this;
this.isSel = true;
IInsertOP sh = shapeLib.SupportedShape(null)[this.drawtype];
sh.MouseOP(1);
e.Handled = true;
}
//throw new NotImplementedException();
}
public void copyVal(gPath obj)
{
drawtype = obj.drawtype;
state = obj.state;
ListPlace = obj.ListPlace;
shapeIndex = obj.shapeIndex;
controlBtn1 = obj.controlBtn1;
controlBtn2 = obj.controlBtn2;
controlBtn3 = obj.controlBtn3;
controlBtn4 = obj.controlBtn4;
foreach (Point p in obj.pList)
{
pList.Add(p);
}
}
}
public class RUse
{
public int Sel = -1;
public int Node = -1;
public System.Windows.Point Point;
}
public class gPoint
{
public System.Windows.Point mouseXY;
public System.Windows.Point point0;
public System.Windows.Point point1;
public System.Windows.Point point2;
public System.Windows.Point point3;
}
/// <summary>
/// 為了維護undo redo, 系統任何操作必需把狀態存起來,
/// </summary>
public class saveState
{
//0: insert, 1:update, 2:delete
public int Action;
//目前圖形串列中的第幾個,為必免順序改變,凡加入的就一直存在(data list)
public int GraphIndex;
//操作前的狀態 fullList 中,操作前該物件所在位置,即最後一個狀態.至少會有新增的狀態.以GraphIndex 去找,其實可以不用記錄
//int preSate;
//操作後的狀態 fullList 中,剛更改的狀態
public int currSate;
public saveState()
{
Action = -1;
GraphIndex = -1;
currSate = -1;
//changeP = 0;
//lastP = -1;
//leastP = 0;
}
public saveState(int a, int b, int c)
{
Action = a;
GraphIndex = b;
currSate = c;
}
}
public class checkHitDraw
{
public int checkHitWhich(List<gPath> l, gPoint gp, int drawType)
{
int whichOne = -1;
for (int i = l.Count - 1; i >= 0; i--)
{
if (drawType < 3 || drawType == 4)
{
if (l[i].controlBtn1 != gp.point0)
continue;
if (l[i].controlBtn2 != gp.point1)
continue;
if (l[i].controlBtn3 != gp.point2)
continue;
if (l[i].controlBtn4 != gp.point3)
continue;
}
if (drawType == 3)
{
if (l[i].drawtype != drawType)
continue;
if (l[i].controlBtn1 != gp.point0)
continue;
if (l[i].controlBtn4 != gp.point3)
continue;
}
whichOne = i;
}
return whichOne;
}
public bool checkHitEllipse(gPoint p) //是否點擊繪製橢圓
{
bool tf = false;
double c_x = (p.point1.X - p.point0.X) / 2;
double c_y = (p.point2.Y - p.point0.Y) / 2;
System.Windows.Point center = new System.Windows.Point(p.point0.X + c_x, p.point0.Y + c_y);
double simpleX = Math.Sqrt((1 - Math.Pow((p.mouseXY.Y - center.Y), 2) / Math.Pow(c_y, 2)) * Math.Pow(c_x, 2));
double simpleY = Math.Sqrt((1 - Math.Pow((p.mouseXY.X - center.X), 2) / Math.Pow(c_x, 2)) * Math.Pow(c_y, 2));
double higherPlaceX = center.X + simpleX;
double lowerPlaceX = center.X - simpleX;
double higherPlaceY = center.Y + simpleY;
double lowerPlaceY = center.Y - simpleY;
if (p.mouseXY.X <= higherPlaceX && p.mouseXY.X >= higherPlaceX - 3)
tf = true;
if (p.mouseXY.X >= lowerPlaceX && p.mouseXY.X <= lowerPlaceX + 3)
tf = true;
if (p.mouseXY.Y <= higherPlaceY && p.mouseXY.Y >= higherPlaceY - 3)
tf = true;
if (p.mouseXY.Y >= lowerPlaceY && p.mouseXY.Y <= lowerPlaceY + 3)
tf = true;
return tf;
}
public bool checkHitRect(gPoint p) //是否點擊繪製矩形
{
bool tf = false;
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))
{
if (p.mouseXY.Y <= p.point2.Y && p.mouseXY.Y >= p.point0.Y)
{
tf = true;
}
}
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))
{
if (p.mouseXY.X <= p.point1.X && p.mouseXY.X >= p.point0.X)
{
tf = true;
}
}
return tf;
}
public bool checkHitLine(System.Windows.Point downPlace, gPath p)
{
bool tf = false;
double m = (p.controlBtn4.Y - p.controlBtn1.Y) / (p.controlBtn4.X - p.controlBtn1.X);
double xm = (downPlace.Y - p.controlBtn1.Y) / m + p.controlBtn1.X;
double ym = (downPlace.X - p.controlBtn1.X) * m + p.controlBtn1.Y;
if (downPlace.X >= xm - 3 && downPlace.X <= xm + 3)
tf = true;
if (downPlace.Y >= ym - 3 && downPlace.Y <= ym + 3)
tf = true;
return tf;
}
public bool checkHitCurve(String Data, gPath p) //是否點擊繪製圓形
{
bool tf = true;
String[] tmpStr = Data.Split(',');
double[] tmpDouStr = new double[tmpStr.Length];
for (int i = 0; i < tmpStr.Length; i++)
{
tmpDouStr[i] = Convert.ToDouble(tmpStr[i]);
}
System.Windows.Point tmpPoint0 = new System.Windows.Point(tmpDouStr[0], tmpDouStr[1]);
System.Windows.Point tmpPoint1 = new System.Windows.Point(tmpDouStr[2], tmpDouStr[3]);
System.Windows.Point tmpPoint2 = new System.Windows.Point(tmpDouStr[4], tmpDouStr[5]);
System.Windows.Point tmpPoint3 = new System.Windows.Point(tmpDouStr[6], tmpDouStr[7]);
if (!tmpPoint0.Equals(p.controlBtn1))
tf = false;
if (!tmpPoint1.Equals(p.controlBtn2))
tf = false;
if (!tmpPoint2.Equals(p.controlBtn3))
tf = false;
if (!tmpPoint3.Equals(p.controlBtn4))
tf = false;
return tf;
}
public int checkHitCorner(System.Windows.Point downPlace, gPath p)
//是否點擊繪製菱形
{
int Node = -1;
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))
{
Node = 0;
}
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))
{
Node = 1;
}
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))
{
Node = 2;
}
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))
{
Node = 3;
}
return Node;
}
public bool checkHitCenter(System.Windows.Point downPlace, gPath p)
{
bool tf = true;
if (downPlace.X > p.controlBtn2.X || downPlace.X < p.controlBtn1.X)
tf = false;
if (downPlace.Y > p.controlBtn4.Y || downPlace.Y < p.controlBtn1.Y)
tf = false;
return tf;
}
}
Last updated