UltimateZoneBuilder/Source/Plugins/BuilderModes/General/LineLengthLabel.cs
MaxED c7696b0464 Fixed, Draw Lines/Rectangle/Circle/Curve modes: line length labels displayed incorrect length.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: line length labels are now displayed the same way as in Draw modes.
Changed, Drag Linedefs/Vertices/Sectors/Things modes: "lock movement to cardinal directions" mode (Alt-Shift-Drag) now locks movement in 4 directions instead of 8 and doesn't snap map elements to nearest grid intersections when they are not aligned to it. 
Added, Visual mode, GZDoom, DECORATE: FORCEXYBILLBOARD flag is now supported.
Added, Visual mode, GLOOME, DECORATE: FLOORSPRITE, CEILSPRITE, WALLSPRITE, ROLLSPRITE and STICKTOPLANE flags are now supported (implementation is somewhat broken ATM and probably doesn't work the same way as in GLOOME, because Windows build with most these features is nowhere to be found...).
Fixed, Visual mode: in some cases Thing brightness was calculated incorrectly.
Updated ZDoom_DECORATE.cfg.
2015-08-25 22:05:14 +00:00

211 lines
5.7 KiB
C#

#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#endregion
#region ================== Namespaces
using System;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Geometry;
using System.Drawing;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
public class LineLengthLabel : IDisposable
{
#region ================== Constants
private const int TEXT_CAPACITY = 15;
private const float TEXT_SCALE = 14f;
private const string VALUE_FORMAT = "0";
#endregion
#region ================== Variables
protected TextLabel label;
protected Vector2D start;
protected Vector2D end;
//mxd. Display options
private bool showangle;
private bool offsetposition;
#endregion
#region ================== Properties
public TextLabel TextLabel { get { return label; } }
//mxd. Display options
public bool ShowAngle { get { return showangle; } set { showangle = value; UpdateText(); } }
public bool OffsetPosition { get { return offsetposition; } set { offsetposition = value; Move(start, end); } }
public PixelColor TextColor { get { return label.Color; } set { label.Color = value; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
public LineLengthLabel()
{
this.showangle = true;
this.offsetposition = true;
// Initialize
Initialize();
}
//mxd. Constructor
public LineLengthLabel(bool showangle, bool offsetposition)
{
this.showangle = showangle;
this.offsetposition = offsetposition;
// Initialize
Initialize();
}
// Constructor
public LineLengthLabel(Vector2D start, Vector2D end)
{
this.showangle = true; //mxd
this.offsetposition = true; //mxd
// Initialize
Initialize();
Move(start, end);
}
//mxd. Constructor
public LineLengthLabel(Vector2D start, Vector2D end, bool showangle, bool offsetposition)
{
this.showangle = showangle;
this.offsetposition = offsetposition;
// Initialize
Initialize();
Move(start, end);
}
// Initialization
private void Initialize()
{
label = new TextLabel(TEXT_CAPACITY);
label.AlignX = TextAlignmentX.Center;
label.AlignY = TextAlignmentY.Middle;
label.Color = General.Colors.Highlight;
label.Backcolor = General.Colors.Background;
label.Scale = TEXT_SCALE;
label.TransformCoords = true;
}
// Disposer
public void Dispose()
{
label.Dispose();
}
#endregion
#region ================== Methods
// This updates the text
protected virtual void UpdateText()
{
Vector2D delta = end - start;
// Update label text
float length = delta.GetLength();
if(showangle)
{
int displayangle = General.ClampAngle((int)Math.Round(Angle2D.RadToDeg(delta.GetAngle())));
label.Text = "l:" + length.ToString(VALUE_FORMAT) + "; a:" + displayangle;
}
else
{
label.Text = length.ToString(VALUE_FORMAT);
}
}
//mxd. This moves the label so it stays on screen and offsets it vertically so it doesn't overlap the line
public virtual void Move(Vector2D start, Vector2D end)
{
// Store before making any adjustments to start/end...
this.start = start;
this.end = end;
// Update text label
UpdateText();
// Check if start/end point is on screen...
Vector2D lt = General.Map.Renderer2D.DisplayToMap(new Vector2D(0.0f, General.Map.Renderer2D.ViewportSize.Height));
Vector2D rb = General.Map.Renderer2D.DisplayToMap(new Vector2D(General.Map.Renderer2D.ViewportSize.Width, 0.0f));
RectangleF viewport = new RectangleF(lt.x, lt.y, rb.x - lt.x, rb.y - lt.y);
bool startvisible = viewport.Contains(start.x, start.y);
bool endvisible = viewport.Contains(end.x, end.y);
// Do this only when one point is visible, an the other isn't
if((!startvisible && endvisible) || (startvisible && !endvisible))
{
Line2D drawnline = new Line2D(start, end);
Line2D[] viewportsides = new[] {
new Line2D(lt, rb.x, lt.y), // top
new Line2D(lt.x, rb.y, rb.x, rb.y), // bottom
new Line2D(lt, lt.x, rb.y), // left
new Line2D(rb.x, lt.y, rb.x, rb.y), // right
};
float u;
foreach(Line2D side in viewportsides)
{
// Modify the start point so it stays on screen
if(!startvisible && side.GetIntersection(drawnline, out u))
{
start = drawnline.GetCoordinatesAt(u);
break;
}
// Modify the end point so it stays on screen
if(!endvisible && side.GetIntersection(drawnline, out u))
{
end = drawnline.GetCoordinatesAt(u);
break;
}
}
}
// Update label position
if(offsetposition)
{
Vector2D perpendicular = (end - start).GetPerpendicular();
float angle = perpendicular.GetAngle();
SizeF textsize = General.Map.GetTextSize(label.Text, label.Scale);
float offset = textsize.Width * Math.Abs((float)Math.Sin(angle)) + textsize.Height * Math.Abs((float)Math.Cos(angle));
perpendicular = perpendicular.GetNormal().GetScaled(offset / 2.0f / General.Map.Renderer2D.Scale);
start += perpendicular;
end += perpendicular;
}
// Apply changes
Vector2D delta = end - start;
label.Rectangle = new RectangleF(start.x + delta.x * 0.5f, start.y + delta.y * 0.5f, 0f, 0f);
}
#endregion
}
}