mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-01 05:10:54 +00:00
c7696b0464
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.
211 lines
5.7 KiB
C#
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
|
|
}
|
|
}
|