using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
namespace _2dGrph
{
public enum Action { Select, Rect, Ellip, Poligon,CenterPoint,MovePoligon,MovePoints }
[Serializable]
public class Status
{
public PathGradientBrush pgbrush;
public Action Mode;
public ExtGrpLst GlbCp;
public Status()
{
Mode=Action.Select;
GlbCp=new ExtGrpLst();
}
}
/*
[Serializable]
public delegate void selectObjEventHandler
(object sender, selectObjEventArgs e);
[Serializable]
public class selectObjEventArgs : EventArgs
{
public Color c1;
public Color c2;
public selectObjEventArgs(Color p, Color q)
{
this.c1 = p;
this.c2 = q;
}
} */
[Serializable]
public class Retta
/* gestisce il percorso tra 2 punti S ed F supponendo assenza di ostacoli*/
{
public float M;
public float Q;
public Retta(PointF s, PointF f)
{
M = 0f;
Q = s.X;
if ((f.X - s.X) != 0 )
{
M = (float)(f.Y - s.Y) / (f.X - s.X);
Q = s.Y - (M * s.X);
}
}
public Retta(float m, float q)
{
M = m;
Q = q;
}
public bool intersect(Retta r)
{
return (!(r.M == this.M));
}
public PointF intersection(Retta r)
{
if (this.intersect(r))
{
float x = ((r.Q - this.Q)/(r.M - this.M));
float y = (this.M * x + this.Q);
return (new PointF(x,y));
}
return (new PointF(0,0));
}
public Retta rettaPerpendicolare(PointF p)
{
float m;
if (this.M == 0)
m = 1;
else
m = (-1 / this.M);
float q = (p.Y - (m * p.X));
return (new Retta(m,q));
}
public PointF mirrowPoint(PointF p)
{
Retta r = this.rettaPerpendicolare(p);
PointF p1 = this.intersection(r);
float dx = (p1.X - p.X);
float dy = (p1.X - p.X);
return (new PointF(p1.X+dx,p1.Y+dy));
}
}
/// <summary>
/// Mouse object to record mouse state into a range.
/// </summary>
[Serializable]
class myMouse
{
Point Pos;
public bool RightDown;
public bool LeftDown;
Point UpperLeft;
Point BottonRight;
public myMouse(Point p1, Point p2)
{
UpperLeft=p1;
BottonRight=p2;
Pos = p1;
RightDown=false;
LeftDown=false;
}
public Point getPos()
{
return (Pos);
}
public int X()
{
return Pos.X;
}
public int Y()
{
return (Pos.Y);
}
public void setPos(Point p)
{
if (p.X > UpperLeft.X & p.X < BottonRight.X & p.Y > UpperLeft.Y &
p.Y < BottonRight.Y)
Pos = p;
}
public void setRange(Point p1, Point p2)
{
UpperLeft=p1;
BottonRight=p2;
if (!(Pos.X > UpperLeft.X & Pos.X < BottonRight.X & Pos.Y > UpperLeft.Y &
Pos.Y < BottonRight.Y))
Pos = p1;
}
//
// Add a timer controll to cast click , double click etc!!
}
/// <summary>
/// Poligon object.
/// </summary>
[Serializable]
public class simpleGrpObj
{
public Color centerColor;
public Color color;
public Point centerPoint;
public ArrayList pointList;
public bool filled;
public simpleGrpObj()
{
pointList = new ArrayList();
color = Color.Black;
centerColor = Color.Black;
centerPoint.X=0;
centerPoint.Y=0;
filled = false;
}
/// <summary>
/// Adds a point at the end of the pointList.
/// </summary>
public void addPoint(PointF p)
{
pointList.Add(p);
filled = true;
}
/// <summary>
/// Clear pointList.
/// </summary>
public void resetPoints()
{
if (pointList.Count>0)
{
filled = false;
pointList.Clear();
}
}
public void addPoints(PointF[] p)
{
pointList.AddRange(p);
filled = true;
}
/// <summary>
/// Search for p1 and if it find, replaces its coordinates with those
/// of p2.
/// </summary>
public void movPoint1(PointF p1,PointF p2)
{
int myIndex = this.pointList.IndexOf( p1 );
this.pointList.Remove(p1);
this.pointList.Insert(myIndex,p2);
}
/// <summary>
/// Moves the point indexed by idx
/// </summary>
public void mvPoint(int idx,float dx,float dy)
{
PointF p1 = new Point(0,0);
ArrayList appo = pointList.GetRange(idx,1);
foreach (PointF p in appo)
{
p1.X = p.X +dx;
p1.Y = p.Y +dy;
}
this.pointList.RemoveAt(idx);
this.pointList.Insert(idx,p1);
}
public void setColor(Color c, Color c1)
{
color = c;
centerColor = c1;
}
public void fillObj()
{
filled = true;
}
public void Transform(Matrix mt)
{
GraphicsPath gp = new GraphicsPath();
gp.StartFigure();
PointF[] appo = new PointF[pointList.Count];
int i = 0;
foreach (PointF p in pointList)
{
appo[i] = p;
i++;
}
if (pointList.Count > 1)
{
gp.AddPolygon(appo);
}
gp.Transform(mt);
Point p2 = new Point (0,0);
resetPoints();
foreach (PointF p1 in gp.PathPoints )
{
p2.X = (int)p1.X;
p2.Y = (int)p1.Y;
addPoint(p2);
}
gp.Reset();
gp.Dispose();
}
public void Move(float dx,float dy)
{
ArrayList appo = new ArrayList();
foreach (PointF p in pointList)
{
PointF p1=new Point(0,0);
p1.X=p.X+dx;
p1.Y=p.Y+dy;
appo.Add(p1);
}
pointList.Clear();
pointList = (ArrayList)appo.Clone();
appo.Clear();
}
}
/// <summary>
/// Poligon object.
/// </summary>
[Serializable]
public class GrpObj :simpleGrpObj
{
public bool selected;
public ArrayList pointsSelected;
public GrpObj()
{
pointList = new ArrayList();
color = Color.Black;
centerColor = Color.Black;
centerPoint.X=0;
centerPoint.Y=0;
filled = false;
selected = false;
pointsSelected=new ArrayList();
}
public void addPointSelected(int i)
{
if (!(pointsSelected.Contains(i)))
pointsSelected.Add(i);
}
/// <summary>
/// If the poligon is selected , moves all selected points
/// </summary>
public void moveSelectedPoints(float dx, float dy)
{
if (selected)
{
foreach (int i in pointsSelected)
{
this.mvPoint(i,dx,dy);
}
}
}
/// <summary>
/// return the selected point in position i
/// </summary>
public PointF getSelectedPoint(int i)
{
int j = 0;
foreach (PointF p in this.pointList)
{
if (i==j)
return (p);
j++;
}
PointF pp = new PointF(0,0);
return(pp);
}
/// <summary>
/// return true if the input point is selected
/// </summary>
public bool isSelected(PointF p)
{
bool result = false;
if (selected)
{
if (this.pointList.Contains(p))
if (pointsSelected.Contains(this.pointList.IndexOf(p)))
result = true;
}
return (result);
}
/*
public void Xmirror()
{
if (this.selected)
{
float minDX = -1;
int i =0;
float dx;
foreach (PointF p in this.pointList)
{
if ((minDX == -1) | (minDX > p.X))
{
minDX = p.X;
}
dx = (-2)*p.X;
//this.mvPoint(i,dx,0);
//this.mvPoint(i,10,0);
p.X = p.X + dx;
i++;
}
this.Move(minDX,0);
}
}
*/
}
/// <summary>
/// Rectangle object. With a fill information
/// </summary>
[Serializable]
public class RectObj
{
public PathGradientBrush pgBrush;
public Rectangle rect;
public bool filled;
//
public RectObj(Rectangle r)
{
this.rect = r;
filled = false;
}
public RectObj(PathGradientBrush pgbrush,Rectangle r)
{
this.rect = r;
filled = true;
pgBrush = pgbrush;
}
public void fillRect(PathGradientBrush pgbrush)
{
filled = true;
pgBrush = pgbrush;
}
}
/// <summary>
/// Graphic list.
/// </summary>
[Serializable]
public class GrpLst
{
public ArrayList list;
public GrpObj selectedObj;
public GrpLst()
{
list=new ArrayList();
}
/// <summary>
/// Add a rectangle.
/// </summary>
public void addObj(GrpObj o)
{
list.Add(o);
selectedObj = o;
}
/// <summary>
/// Add a Point to selected poligon .
/// </summary>
public void addPoint(Point p)
{
if (!(selectedObj == null))
selectedObj.addPoint(p);
}
/// <summary>
/// Removes selected poligon . Not USED
/// </summary>
public void remRect()
{
list.Remove(selectedObj);
selectedObj=null;
}
/// <summary>
/// Clear all poligons .
/// </summary>
public void Clear()
{
if (list.Count>0)
list.Clear();
}
public ArrayList CopyList()
{
ArrayList appo = new ArrayList();
if (this.list.Count>0)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
GrpObj obj1 = new GrpObj();
foreach (PointF p in obj.pointList)
{
PointF p1 = new PointF(0,0);
p1.X = p.X;
p1.Y = p.Y;
obj1.pointList.Add(p1);
}
obj1.color = obj.color;
obj1.centerColor = obj.centerColor;
obj1.centerPoint = obj.centerPoint;
appo.Add(obj1);
}
}
return (appo);
}
/// <summary>
/// Apply a trasformation matrix to ALL poligons.
/// </summary>
public void TransformaLL(Matrix mt)
{
foreach (GrpObj obj in list)
{
obj.Transform(mt);
}
}
}
/// <summary>
/// Extended Graphic list.
/// </summary>
[Serializable]
public class ExtGrpLst: GrpLst
{
// public event selectObjEventHandler selectObjMsg;
public ArrayList cpList;
public bool almostOneSelected;
public ExtGrpLst()
{
this.list=new ArrayList();
this.cpList = new ArrayList(); // cp poligons
almostOneSelected = false;
}
/* public ExtGrpLst(canvas t)
{
this.list=new ArrayList();
this.cpList = new ArrayList(); // cp poligons
almostOneSelected = false;
this.selectObjMsg += new selectObjEventHandler(t.OnselectObj);
}
public ExtGrpLst(animator t)
{
this.list=new ArrayList();
this.cpList = new ArrayList(); // cp poligons
almostOneSelected = false;
this.selectObjMsg += new selectObjEventHandler(t.OnselectObj);
} */
/// <summary>
/// Selects a set of poligons.
/// </summary>
public void selection(Rectangle r)
{
almostOneSelected = false;
int i = 0;
almostOneSelected = false;
foreach (GrpObj obj in this.list) //POLIGONS
{
obj.pointsSelected.Clear();
obj.selected = false;
int j = 0;
foreach (PointF p in obj.pointList) //POLIGON'S POINTS
{
Point p1 = new Point();
p1.X = (int)p.X;
p1.Y = (int)p.Y;
if (r.Contains(p1))
{
// add pol i and point j to polpointsselected: start
obj.addPointSelected(j);
// add pol i and point j to polpointsselected: end
obj.selected = true;
////////////////////////////////////////
/* if (selectObjMsg != null)
{
selectObjMsg(this, new selectObjEventArgs(obj.color,obj.centerColor));
}*/
almostOneSelected = true;
this.selectedObj = obj;
}
j++;
}
i++;
}
}
/// <summary>
/// Apply a trasformation matrix to the "selected" poligons.
/// </summary>
public void Transform(Matrix mt)
{
foreach (GrpObj obj in list)
{
if (obj.selected)
{
obj.Transform(mt);
}
}
}
/// <summary>
/// Moves the "selected" poligons.
/// </summary>
public void moveSelected(float dx,float dy)
{
foreach (GrpObj obj in list)
{
if (obj.selected)
{
obj.Move(dx,dy);
}
}
}
/// <summary>
/// Removes the "selected" poligons.
/// </summary>
public void rmSelected()
{
if (this.almostOneSelected)
{
ArrayList appoList = new ArrayList();
cpSelected();
foreach (GrpObj obj in list)
{
if (obj.selected)
{
appoList.Add(obj);//save refernce to selected
}
}
foreach (GrpObj obj in appoList)
{
list.Remove(obj);
}
appoList.Clear();
}
}
/// <summary>
/// Copy the "selected" poligons.
/// </summary>
private void cpSelected()
// not used!!!!!!!!!!!!!!
{
//cpList=(ArrayList)list.Clone();
//ArrayList appoList = new ArrayList();
if (cpList.Count>0)
{ cpList.Clear(); }
foreach (GrpObj obj in list)
{
if (obj.selected)
{
// create new poligon
GrpObj obj2 = new GrpObj();
obj2.pointList = (ArrayList)obj.pointList.Clone();
obj2.color = obj.color;
obj2.centerPoint = obj.centerPoint;
obj2.centerColor = obj.centerColor;
obj2.filled = obj.filled;
cpList.Add(obj2);
}
}
}
/// <summary>
/// Paste the "selected" poligons and apply a trasformation.
/// </summary>
private void pasteSelected()
{
this.undoSelection();
if (cpList.Count>0)
{
this.almostOneSelected = true;
//this.list.AddRange(cpList)
foreach (GrpObj obj in cpList)
{
//obj.Transform(mt);
list.Add(obj);
obj.selected=true;
}
}
// recopy for repast
cpSelected();
}
/// <summary>
/// Apply a trasformation matrix to ALL poligons.
/// </summary>
/*public void TransformaLL(Matrix mt)
{
foreach (GrpObj obj in list)
{
obj.Transform(mt);
}
} */
/// <summary>
/// Cut selected points.
/// </summary>
public void cutSelectedPoints()
{
if (almostOneSelected)
{
foreach (GrpObj obj1 in this.list) //SELECTED POLIGONS
{
if (obj1.selected)
{
ArrayList appo = new ArrayList();
int nSelected = obj1.pointsSelected.Count;
if ((nSelected > 0) & ((obj1.pointList.Count - nSelected) > 2 ))
{
foreach (PointF p in obj1.pointList) //POINTS
{
if (!(obj1.isSelected(p))) //if not selected point
{
PointF p1 = new PointF();
p1.X = p.X;
p1.Y = p.Y;
appo.Add(p1); //store in appo list
}
}
obj1.pointList.Clear();
foreach (PointF p in appo)
{
PointF p1 = new PointF();
p1.X = p.X;
p1.Y = p.Y;
obj1.pointList.Add(p1);
}
obj1.pointsSelected.Clear();
}
}
}
}
}
/// <summary>
/// Add points.
/// </summary>
public void addPoints()
{
if (almostOneSelected)
{
foreach (GrpObj obj1 in this.list) //SELECTED POLIGONS
{
if (obj1.selected)
{
int nSelected = obj1.pointsSelected.Count;
if (nSelected == 1)
{
foreach (int i in obj1.pointsSelected) //POINTS
{
PointF p2 = obj1.getSelectedPoint(i);
PointF p1 = new PointF();
p1.X = p2.X +10;
p1.Y = p2.Y +10;
obj1.pointList.Insert(i,p1);
}
//obj1.pointsSelected.Clear();
}
}
}
}
}
/// <summary>
/// Undo Select of poligons.
/// </summary>
public void undoSelection()
{
if (almostOneSelected)
{
foreach (GrpObj obj1 in this.list) //SELECTED POLIGONS
{
obj1.selected = false;
}
almostOneSelected = false;
}
}
public ArrayList getSelectedTarsformedList(float dx,float dy)
{
ArrayList appo = new ArrayList();
if (almostOneSelected)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
if (obj.selected)
{
GrpObj obj1 = new GrpObj();
foreach (PointF p in obj.pointList)
{
PointF p1 = new PointF(0,0);
p1.X = p.X + dx;
p1.Y = p.Y + dy;
obj1.pointList.Add(p1);
}
appo.Add(obj1);
}
}
}
return (appo);
}
public ArrayList getSelectedList()
{
ArrayList appo = new ArrayList();
if (almostOneSelected)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
if (obj.selected)
{
GrpObj obj1 = new GrpObj();
foreach (PointF p in obj.pointList)
{
PointF p1 = new PointF(0,0);
p1.X = p.X;
p1.Y = p.Y;
obj1.pointList.Add(p1);
}
obj1.color = obj.color;
obj1.centerColor = obj.centerColor;
obj1.centerPoint = obj.centerPoint;
appo.Add(obj1);
}
}
}
return (appo);
}
public ArrayList getSelectedTarsformedList(Matrix mt)
{
ArrayList appo = new ArrayList();
if (almostOneSelected)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
if (obj.selected)
{
GrpObj obj1 = new GrpObj();
foreach (PointF p in obj.pointList)
{
PointF p1 = new PointF(0,0);
p1.X = p.X;
p1.Y = p.Y;
obj1.pointList.Add(p1);
}
obj1.Transform(mt);
appo.Add(obj1);
}
}
}
return (appo);
}
public ArrayList getSelectedPointMovedList(float dx,float dy)
{
ArrayList appo = new ArrayList();
if (almostOneSelected)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
if (obj.selected)
{
GrpObj obj1 = new GrpObj();
foreach (PointF p in obj.pointList)
{
PointF p1 = new PointF(0,0);
if (obj.isSelected(p))
{
p1.X = p.X + dx;
p1.Y = p.Y + dy;
}
else
{
p1.X = p.X;
p1.Y = p.Y;
}
obj1.pointList.Add(p1);
}
appo.Add(obj1);
}
}
}
return (appo);
}
/// <summary>
/// If the poligon is selected , moves all selected points
/// </summary>
public void moveSelectedPoints(float dx, float dy)
{
foreach (GrpObj o in this.list)
{
if (o.selected)
{
o.moveSelectedPoints(dx,dy);
}
}
}
/// <summary>
/// Sets the color of center point for all selected poligs
/// </summary>
public void selectionCenterColor(Color c)
{
if (almostOneSelected)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
if (obj.selected)
{
obj.centerColor = c;
}
}
}
}
/// <summary>
/// Sets the color of all selected poligs
/// </summary>
public void selectionColor(Color c)
{
if (almostOneSelected)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
if (obj.selected)
{
obj.color = c;
}
}
}
}
/// <summary>
/// Sets the color of all selected poligs
/// </summary>
public void selectAll()
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
obj.selected = true;
}
}
/// <summary>
/// Sets the center point color of all selected poligs
/// </summary>
public void selectionCenterPoint(Point p)
{
if (almostOneSelected)
{
foreach (GrpObj obj in this.list) //SELECTED POLIGONS
{
if (obj.selected)
{
obj.centerPoint = p;
}
}
}
}
/// <summary>
/// move up (Z ordering) selected poligons
/// </summary>
public void moveUp()
{
if (almostOneSelected)
{
this.cpSelected();
this.rmSelected();
this.pasteSelected();
}
}
/// <summary>
/// X mirror (Z ordering) selected poligons
/// </summary>
public void Xmirror()
{
if (almostOneSelected)
{
// copies selected poligons
//this.cpSelected();
//this.rmSelected();
//this.pasteSelected();
// Now do the X mirror
ArrayList newPols = new ArrayList();
foreach (GrpObj o in this.list)
{
if (o.selected)
{
o.selected = false;
PointF[] appo = new PointF[o.pointList.Count];
int i = 0;
float minDX = -1;
float dx;
foreach (PointF p in o.pointList)
{
if (p.X < 0)
{
minDX = -1; //abort
break;
}
if ( (minDX < 0) | (minDX > p.X) )
{
minDX = p.X;
}
dx = (-1)*p.X;
PointF p1 = new PointF(dx,p.Y);
appo[i]=p1;
i++;
}
if (minDX > 0)
{
GrpObj o1 = new GrpObj();
o1.addPoints(appo);
o1.selected = true;
o1.color = o.color;
o1.centerPoint = o.centerPoint;
o1.centerColor = o.centerColor;
o1.Move((minDX*2),0);
newPols.Add(o1);
}
}
}
this.list.AddRange(newPols);
}
}
/// <summary>
/// Y mirror (Z ordering) selected poligons
/// </summary>
public void Ymirror()
{
if (almostOneSelected)
{
ArrayList newPols = new ArrayList();
foreach (GrpObj o in this.list)
{
if (o.selected)
{
o.selected = false;
PointF[] appo = new PointF[o.pointList.Count];
int i = 0;
float minDY = -1;
float dy;
foreach (PointF p in o.pointList)
{
if (p.Y < 0)
{
minDY = -1; //abort
break;
}
if ( (minDY < 0) | (minDY > p.Y) )
{
minDY = p.Y;
}
dy = (-1)*p.Y;
PointF p1 = new PointF(p.X,dy);
appo[i]=p1;
i++;
}
if (minDY > 0)
{
GrpObj o1 = new GrpObj();
o1.addPoints(appo);
o1.selected = true;
o1.color = o.color;
o1.centerPoint = o.centerPoint;
o1.centerColor = o.centerColor;
o1.Move(0,(minDY*2));
newPols.Add(o1);
}
}
}
this.list.AddRange(newPols);
}
}
}
/// <summary>
/// Undo vector buffer.
/// </summary>
public class UndoBuffer
{
public ExtGrpLst[] undoList;
public int idx;
public int buffSize;
public bool almostOne;
public UndoBuffer( int i)
{
if (i > 0)
{
buffSize = i;
undoList = new ExtGrpLst[i];
}
else
{
buffSize = 0;
}
idx = 0;
almostOne = false;
}
public void add2Buff(ExtGrpLst g)
{
if (!(g == null))
{
ExtGrpLst g1 = new ExtGrpLst();
g1.list = g.CopyList();
if (idx == buffSize)
{
idx=0;
}
undoList[idx] = g1;
idx++;
almostOne = true;
}
}
public ExtGrpLst getBuff()
{
if (idx == 0)
{
idx = buffSize;
}
idx --;
return undoList[idx];
}
}
/// <summary>
/// Animation.
/// </summary>
[Serializable]
public class Anim
{
public ArrayList frameList;
public GrpLst Ori;
public int nFrames;
public Anim( GrpLst o)
{
this.frameList = new ArrayList();
Ori = o;
frameList.Add(o);
}
public GrpLst getFrame(int i)
{
if (i <= frameList.Count)
{
int j = 0;
foreach (GrpLst g in frameList)
{
if (i==j)
return (g);
j++;
}
}
return(null);
}
public GrpLst[] getFrameArray()
{
GrpLst[] appo;
appo = new GrpLst[frameList.Count];
if ( frameList.Count>0)
{
//appo = new GrpLst[frameList.Count];
int j = 0;
foreach (GrpLst g in frameList)
{
appo[j] = g;
j++;
}
}
return appo;
}
public bool setFrame(int i,GrpLst o)
{
if (i < frameList.Count)
{
frameList.RemoveAt(i);
frameList.Insert(i,o);
return true;
}
else
{
frameList.Add(o);
}
return false;
}
public void addFrame(GrpLst o)
{
frameList.Add(o);
}
public void Clear()
{
frameList.Clear();
}
/// <summary>
/// Apply a trasformation matrix to the "selected" poligons.
/// </summary>
public void allTransform(Matrix mt)
{
foreach (GrpLst l in frameList)
{
l.TransformaLL(mt);
}
}
}
}