UltimateZoneBuilder/Source/Plugins/BuilderModes/ClassicModes/DrawEllipseMode.cs

160 lines
4 KiB
C#
Raw Normal View History

#region ================== Namespaces
using System;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Geometry;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
[EditMode(DisplayName = "Draw Ellipse Mode",
SwitchAction = "drawellipsemode",
AllowCopyPaste = false,
Volatile = true,
Optional = false)]
public class DrawEllipseMode : DrawRectangleMode
{
#region ================== Variables
//interface
private Docker settingsdocker;
private DrawEllipseOptionsPanel panel;
#endregion
#region ================== Constructor
2013-03-18 13:52:27 +00:00
public DrawEllipseMode() {
undoName = "Ellipse draw";
shapeName = "ellipse";
}
#endregion
#region ================== Settings panel
override protected void setupInterface() {
maxSubdivisions = 512;
minSubdivisions = 6;
//Add options docker
panel = new DrawEllipseOptionsPanel();
panel.MaxSubdivisions = maxSubdivisions;
panel.MinSubdivisions = minSubdivisions;
panel.OnValueChanged += OptionsPanelOnValueChanged;
settingsdocker = new Docker("drawrectangle", "Draw Ellipse", panel);
}
override protected void addInterface() {
General.Interface.AddDocker(settingsdocker);
General.Interface.SelectDocker(settingsdocker);
bevelWidth = panel.Aquity;
subdivisions = panel.Subdivisions;
2013-03-18 13:52:27 +00:00
}
override protected void removeInterface() {
General.Interface.RemoveDocker(settingsdocker);
}
#endregion
#region ================== Methods
override protected Vector2D[] getShape(Vector2D pStart, Vector2D pEnd) {
//no shape
if (pEnd.x == pStart.x && pEnd.y == pStart.y)
return new Vector2D[0];
2013-03-18 13:52:27 +00:00
//line
if(pEnd.x == pStart.x || pEnd.y == pStart.y)
return new[] { pStart, pEnd };
2013-03-18 13:52:27 +00:00
//got shape
int bevelSign = (bevelWidth > 0 ? 1 : -1);
currentBevelWidth = Math.Min(Math.Abs(bevelWidth), Math.Min(width, height) / 2) * bevelSign;
Vector2D[] shape = new Vector2D[subdivisions + 1];
bool doBevel = false;
int hw = width / 2;
int hh = height / 2;
Vector2D center = new Vector2D(pStart.x + hw, pStart.y + hh);
float curAngle = 0;
float angleStep = -Angle2D.PI / subdivisions * 2;
int px, py;
for (int i = 0; i < subdivisions; i++) {
if (doBevel) {
px = (int)(center.x - (float)Math.Sin(curAngle) * (hw + currentBevelWidth));
py = (int)(center.y - (float)Math.Cos(curAngle) * (hh + currentBevelWidth));
} else {
px = (int)(center.x - (float)Math.Sin(curAngle) * hw);
py = (int)(center.y - (float)Math.Cos(curAngle) * hh);
}
doBevel = !doBevel;
shape[i] = new Vector2D(px, py);
curAngle += angleStep;
}
//add final point
shape[subdivisions] = shape[0];
return shape;
}
protected override string getHintText() {
return "BVL: "+bevelWidth+"; VERTS: "+subdivisions;
}
#endregion
#region ================== Events
private void OptionsPanelOnValueChanged(object sender, EventArgs eventArgs) {
bevelWidth = panel.Aquity;
subdivisions = Math.Min(maxSubdivisions, panel.Subdivisions);
Update();
}
#endregion
#region ================== Actions
override protected void increaseSubdivLevel() {
if (subdivisions < maxSubdivisions) {
subdivisions += 2;
panel.Subdivisions = subdivisions;
Update();
}
}
override protected void decreaseSubdivLevel() {
if (subdivisions > minSubdivisions) {
subdivisions -= 2;
panel.Subdivisions = subdivisions;
Update();
}
}
protected override void increaseBevel() {
if(points.Count < 2 || currentBevelWidth == bevelWidth || bevelWidth < 0) {
bevelWidth += General.Map.Grid.GridSize;
panel.Aquity = bevelWidth;
Update();
}
}
protected override void decreaseBevel() {
if(currentBevelWidth == bevelWidth || bevelWidth > 0) {
bevelWidth -= General.Map.Grid.GridSize;
panel.Aquity = bevelWidth;
Update();
}
}
#endregion
}
}