using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.ComponentModel;
using System.Threading;
using System.Globalization;
using BauzoidNET.graphics;
using BauzoidNET.graphics.sprite;
using BauzoidNET.math;
using OrderedPropertyGrid;
namespace ShapeEditor
.file.shapes
{
[TypeConverter
(typeof(PropertySorter
))]
public class EllipseElement
: BaseShapeElement
{
public const int NUM_HANDLES
= 4;
private Vector2
[] mHandles
= new Vector2
[NUM_HANDLES
];
public float centerX
= 0;
public float centerY
= 0;
public float radiusX
= 0;
public float radiusY
= 0;
[Category
("Coordinates"), PropertyOrder
(10)]
public float CenterX
{
get
{ return centerX
; }
set
{ centerX
= value
; }
}
[Category
("Coordinates"), PropertyOrder
(11)]
public float CenterY
{
get
{ return centerY
; }
set
{ centerY
= value
; }
}
[Category
("Coordinates"), PropertyOrder
(12)]
public float RadiusX
{
get
{ return radiusX
; }
set
{ radiusX
= value
; }
}
[Category
("Coordinates"), PropertyOrder
(13)]
public float RadiusY
{
get
{ return radiusY
; }
set
{ radiusY
= value
; }
}
public EllipseElement
(Document doc,
string name,
float _centerX,
float _centerY,
float _radiusX,
float _radiusY
)
: base(doc, name
)
{
centerX
= _centerX
; centerY
= _centerY
; radiusX
= _radiusX
; radiusY
= _radiusY
;
for (int i
= 0; i
< NUM_HANDLES
; i
++)
mHandles
[i
] = new Vector2
();
}
public override void Render
(SpriteTransform transform
)
{
float z
= mDocument
.Owner.ZoomFactor;
float x1
= centerX
- radiusX
;
float y1
= centerY
- radiusY
;
float x2
= centerX
+ radiusX
;
float y2
= centerY
+ radiusY
;
x1
*= z
;
y1
*= z
;
x2
*= z
;
y2
*= z
;
//RenderUtil.drawQuad(MainForm.App.getGraphics(), centerX * z, centerY * z, (centerX + radiusX) * z, (centerY + radiusY) * z, transform, Document.SHAPE_COLOR);
RenderUtil
.drawEllipse(MainForm
.App.getGraphics(), x1, y1, x2, y2, transform, Document
.SHAPE_COLOR);
}
public override void RenderSelected
(SpriteTransform transform,
bool drawHandles
= true)
{
float z
= mDocument
.Owner.ZoomFactor;
//RenderUtil.drawQuad(MainForm.App.getGraphics(), centerX * z, centerY * z, (centerX + radiusX) * z, (centerY + radiusY) * z, transform, Document.SHAPE_COLOR_SELECTED);
float x1
= centerX
- radiusX
;
float y1
= centerY
- radiusY
;
float x2
= centerX
+ radiusX
;
float y2
= centerY
+ radiusY
;
x1
*= z
;
y1
*= z
;
x2
*= z
;
y2
*= z
;
RenderUtil
.drawEllipse(MainForm
.App.getGraphics(), x1, y1, x2, y2, transform, Document
.SHAPE_COLOR_SELECTED);
if (drawHandles
)
{
for (int i
= 0; i
< NUM_HANDLES
; i
++)
mDocument
.RenderHandle(mHandles
[i
].x, mHandles
[i
].y, transform
);
/*mDocument.RenderHandle(centerX - radiusX, centerY - radiusY, transform);
mDocument.RenderHandle((centerX + radiusX), centerY - radiusY, transform);
mDocument.RenderHandle(centerX - radiusX, (centerY + radiusY), transform);
mDocument.RenderHandle((centerX + radiusX), (centerY + radiusY), transform);*/
}
}
public override int GetNumHandles
() { return NUM_HANDLES
; }
public override int FindHandleAt
(float px,
float py
)
{
UpdateHandles
();
for (int i
= 0; i
< NUM_HANDLES
; i
++)
{
if (IsInsideHandle
(px, py, mHandles
[i
].x, mHandles
[i
].y))
return i
;
}
return -1;
}
public override bool IsInside
(float px,
float py
)
{
px
-= mDocument
.Sprite.transform.x;
py
-= mDocument
.Sprite.transform.y;
px
/= mDocument
.Owner.ZoomFactor;
py
/= mDocument
.Owner.ZoomFactor;
//return ((px >= centerX) && (px <= (centerX + radiusX)) && (py >= centerY) && (py <= (centerY + radiusY)));
if (radiusX
== 0)
return false;
if (radiusY
== 0)
return false;
float dx
= (px
- centerX
);
float dy
= (py
- centerY
);
if (((dx
* dx
) / (radiusX
* radiusX
) + (dy
* dy
) / (radiusY
* radiusY
)) <= 1)
return true;
return false;
// return (((dx*dx)/(radiusX*radiusX) + (dy*dy)/(radiusY*radiusY)) <= 1);
}
public void UpdateHandles
()
{
mHandles
[0].set(centerX
- radiusX, centerY
- radiusY
);
mHandles
[1].set(centerX
+ radiusX, centerY
- radiusY
);
mHandles
[2].set(centerX
- radiusX, centerY
+ radiusY
);
mHandles
[3].set(centerX
+ radiusX, centerY
+ radiusY
);
}
public override Cursor GetCursor
(int handle
)
{
if (handle
== 0)
return Cursors
.SizeNWSE;
else if (handle
== 1)
return Cursors
.SizeNESW;
else if (handle
== 2)
return Cursors
.SizeNESW;
else if (handle
== 3)
return Cursors
.SizeNWSE;
return Cursors
.Arrow;
}
public bool IsInsideHandle
(float px,
float py,
float handleX,
float handleY
)
{
px
-= mDocument
.Sprite.transform.x;
py
-= mDocument
.Sprite.transform.y;
px
/= mDocument
.Owner.ZoomFactor;
py
/= mDocument
.Owner.ZoomFactor;
if ((Math
.Abs(handleX
- px
) < Document
.HANDLE_SIZE / 2) && (Math
.Abs(handleY
- py
) < Document
.HANDLE_SIZE / 2))
return true;
return false;
}
public override void DragHandle
(int handle,
float dx,
float dy
)
{
UpdateHandles
();
dx
/= mDocument
.Owner.ZoomFactor;
dy
/= mDocument
.Owner.ZoomFactor;
if (handle
== 0)
{
// upper left
centerX
+= dx
/2; radiusX
-= dx
/2;
centerY
+= dy
/2; radiusY
-= dy
/2;
}
else if (handle
== 1)
{
// upper right
centerX
+= dx
/2; radiusX
+= dx
/2;
centerY
+= dy
/2; radiusY
-= dy
/2;
}
else if (handle
== 2)
{
// lower left
centerX
+= dx
/2; radiusX
-= dx
/2;
centerY
+= dy
/2; radiusY
+= dy
/2;
}
else if (handle
== 3)
{
// lower right
centerX
+= dx
/2; radiusX
+= dx
/2;
centerY
+= dy
/2; radiusY
+= dy
/2;
}
mDocument
.SetDirty();
UpdateHandles
();
UpdateName
();
}
public override void DragMove
(float dx,
float dy
)
{
centerX
+= dx
/ mDocument
.Owner.ZoomFactor;
centerY
+= dy
/ mDocument
.Owner.ZoomFactor;
mDocument
.SetDirty();
UpdateHandles
();
UpdateName
();
}
public void UpdateName
()
{
//ShapeName = "rect " + Math.Min(centerX, centerX + radiusX) + ", " + Math.Min(centerY, centerY + radiusY) + ", " + Math.Abs(radiusX) + ", " + Math.Abs(radiusY);
ShapeName
= "ellipse " + centerX
+ ", " + centerY
+ ", " + radiusX
+ ", " + radiusY
;
typeof(ListBox
).InvokeMember("RefreshItems", BindingFlags
.NonPublic | BindingFlags
.Instance | BindingFlags
.InvokeMethod,
null, mDocument
.Owner.ElementsListBox,
new object[] { });
}
public override void FixCoordinates
()
{
if (radiusX
< 0)
{
radiusX
= -radiusX
;
/*centerX = centerX + radiusX;
radiusX = -radiusX;*/
}
if (radiusY
< 0)
{
radiusY
= -radiusY
;
/*centerY = centerY + radiusY;
radiusY = -radiusY;*/
}
}
public override void WriteFile
(System.IO.TextWriter tw
)
{
Thread
.CurrentThread.CurrentCulture = CultureInfo
.InvariantCulture;
tw
.WriteLine("ellipse " + centerX
+ ", " + centerY
+ ", " + radiusX
+ ", " + radiusY
+ ";");
}
}
}