mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-27 14:12:16 +00:00
59c4a75b11
Added "doomthingrotationangles" Game Configuration property. When enabled, editor actions related to changing thing angle will snap the resulting angle to 45 degree increments. This property is set to true for vanilla game configurations. Fixed a crash when changing game configuration from one without Thing actions support to one with them while in Things mode. Fixed, cosmetic, DB2 bug: current editing mode button was deselected after reloading resources. Updated documentation ("Game Configuration - Basic Settings" page).
212 lines
5.6 KiB
C#
212 lines
5.6 KiB
C#
#region Namespaces
|
|
|
|
//Downloaded from
|
|
//Visual C# Kicks - http://vckicks.110mb.com
|
|
//The Code Project - http://www.codeproject.com
|
|
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Windows.Forms;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.Controls
|
|
{
|
|
public partial class AngleControlEx : UserControl
|
|
{
|
|
#region Variables
|
|
|
|
private int angle;
|
|
private int angleoffset;
|
|
|
|
private Rectangle drawRegion;
|
|
private const int drawOffset = 2;
|
|
private const int markScaler = 5;
|
|
private Point origin;
|
|
|
|
private bool doomangleclamping;
|
|
|
|
//UI colors
|
|
private readonly Color fillColor = SystemColors.Window;
|
|
private readonly Color fillInactiveColor = SystemColors.Control;
|
|
private readonly Color outlineColor = SystemColors.WindowFrame;
|
|
private readonly Color outlineInactiveColor = SystemColors.ControlDarkDark;
|
|
private readonly Color needleColor = SystemColors.ControlText;
|
|
private readonly Color needleInactiveColor = SystemColors.ControlDarkDark;
|
|
private readonly Color marksColor = SystemColors.ActiveBorder;
|
|
private readonly Color marksInactiveColor = SystemColors.ControlDark;
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public event EventHandler AngleChanged;
|
|
|
|
public int Angle { get { return (angle == NO_ANGLE ? NO_ANGLE : angle - angleoffset); } set { angle = (value == NO_ANGLE ? NO_ANGLE : value + angleoffset); this.Refresh(); } }
|
|
public int AngleOffset { get { return angleoffset; } set { angleoffset = value; this.Refresh(); } }
|
|
public bool DoomAngleClamping { get { return doomangleclamping; } set { doomangleclamping = value; } }
|
|
public const int NO_ANGLE = int.MinValue;
|
|
|
|
#endregion
|
|
|
|
public AngleControlEx()
|
|
{
|
|
InitializeComponent();
|
|
this.DoubleBuffered = true;
|
|
}
|
|
|
|
#region Methods
|
|
|
|
private void SetDrawRegion()
|
|
{
|
|
drawRegion = new Rectangle(0, 0, this.Width, this.Height);
|
|
drawRegion.X += 2;
|
|
drawRegion.Y += 2;
|
|
drawRegion.Width -= 4;
|
|
drawRegion.Height -= 4;
|
|
|
|
origin = new Point(drawRegion.Width / 2 + drawOffset, drawRegion.Height / 2 + drawOffset);
|
|
|
|
this.Refresh();
|
|
}
|
|
|
|
private static PointF DegreesToXY(float degrees, float radius, Point origin)
|
|
{
|
|
PointF xy = new PointF();
|
|
float radians = degrees * Angle2D.PI / 180.0f;
|
|
|
|
xy.X = (float)Math.Cos(radians) * radius + origin.X;
|
|
xy.Y = (float)Math.Sin(-radians) * radius + origin.Y;
|
|
|
|
return xy;
|
|
}
|
|
|
|
private static int XYToDegrees(Point xy, Point origin)
|
|
{
|
|
float xDiff = xy.X - origin.X;
|
|
float yDiff = xy.Y - origin.Y;
|
|
return ((int)Math.Round(Math.Atan2(-yDiff, xDiff) * 180.0 / Angle2D.PI) + 360) % 360;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Events
|
|
|
|
private void AngleSelector_Load(object sender, EventArgs e)
|
|
{
|
|
SetDrawRegion();
|
|
}
|
|
|
|
private void AngleSelector_SizeChanged(object sender, EventArgs e)
|
|
{
|
|
this.Height = this.Width; // Keep it there and keep it square!
|
|
SetDrawRegion();
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
Graphics g = e.Graphics;
|
|
|
|
Pen outline;
|
|
Pen needle;
|
|
Pen marks;
|
|
SolidBrush fill;
|
|
Brush center;
|
|
|
|
if(this.Enabled)
|
|
{
|
|
outline = new Pen(outlineColor, 2.0f);
|
|
fill = new SolidBrush(fillColor);
|
|
needle = new Pen(needleColor);
|
|
center = new SolidBrush(needleColor);
|
|
marks = new Pen(marksColor);
|
|
}
|
|
else
|
|
{
|
|
outline = new Pen(outlineInactiveColor, 2.0f);
|
|
fill = new SolidBrush(fillInactiveColor);
|
|
needle = new Pen(needleInactiveColor);
|
|
center = new SolidBrush(needleInactiveColor);
|
|
marks = new Pen(marksInactiveColor);
|
|
}
|
|
|
|
Rectangle originSquare = new Rectangle(origin.X - 1, origin.Y - 1, 3, 3);
|
|
|
|
//Draw circle
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|
g.DrawEllipse(outline, drawRegion);
|
|
g.FillEllipse(fill, drawRegion);
|
|
|
|
// Draw angle marks
|
|
int offset = this.Height / markScaler;
|
|
for(int i = 0; i < 360; i += 45)
|
|
{
|
|
PointF p1 = DegreesToXY(i, origin.X - 6, origin);
|
|
PointF p2 = DegreesToXY(i, origin.X - offset, origin);
|
|
g.DrawLine(marks, p1, p2);
|
|
}
|
|
|
|
// Draw needle
|
|
if(angle != NO_ANGLE)
|
|
{
|
|
PointF anglePoint = DegreesToXY(angle, origin.X - 4, origin);
|
|
g.DrawLine(needle, origin, anglePoint);
|
|
}
|
|
|
|
g.SmoothingMode = SmoothingMode.HighSpeed; //Make the square edges sharp
|
|
g.FillRectangle(center, originSquare);
|
|
|
|
//mxd. Dispose brushes
|
|
fill.Dispose();
|
|
center.Dispose();
|
|
outline.Dispose();
|
|
marks.Dispose();
|
|
needle.Dispose();
|
|
|
|
base.OnPaint(e);
|
|
}
|
|
|
|
private void AngleSelector_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
int thisAngle = XYToDegrees(new Point(e.X, e.Y), origin);
|
|
|
|
if(e.Button == MouseButtons.Left)
|
|
{
|
|
thisAngle = (int)Math.Round(thisAngle / 45f) * 45;
|
|
if(thisAngle == 360) thisAngle = 0;
|
|
}
|
|
|
|
if(thisAngle != angle)
|
|
{
|
|
angle = thisAngle;
|
|
if(!this.DesignMode && AngleChanged != null) AngleChanged(this, EventArgs.Empty); //Raise event
|
|
this.Refresh();
|
|
}
|
|
}
|
|
|
|
private void AngleSelector_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if(e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
|
|
{
|
|
int thisAngle = XYToDegrees(new Point(e.X, e.Y), origin);
|
|
|
|
if(e.Button == MouseButtons.Left || doomangleclamping)
|
|
{
|
|
thisAngle = (int)Math.Round(thisAngle / 45f) * 45;
|
|
if(thisAngle == 360) thisAngle = 0;
|
|
}
|
|
|
|
if(thisAngle != angle)
|
|
{
|
|
angle = thisAngle;
|
|
if(!this.DesignMode && AngleChanged != null) AngleChanged(this, EventArgs.Empty); //Raise event
|
|
this.Refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|