mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 22:01:45 +00:00
Added, Drag Vertices\Linedefs\Sectors\Edit Selection modes: sidedefs facing outside of current selection are now reattached/added/removed after moving the selection.
Currently this will work as intended only if the selection ends up either completely inside a single sector or completely outside of any sector. Also this logic won't be applied if the selection contains the lines with only start or end vertex selected. Internal: some TextLabel refactoring.
This commit is contained in:
parent
5ab50fc981
commit
13aabd4257
21 changed files with 355 additions and 53 deletions
|
@ -2171,6 +2171,18 @@ zdoom
|
||||||
}
|
}
|
||||||
71 // Teleport_NoFog
|
71 // Teleport_NoFog
|
||||||
{
|
{
|
||||||
|
arg1
|
||||||
|
{
|
||||||
|
title = "Teleport Dest. angle usage";
|
||||||
|
type = 11;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
0 = "Don't change angle and velocity (Hexen-compat)";
|
||||||
|
1 = "Always use the teleport exit's angle (Strife-compat)";
|
||||||
|
2 = "Adjust relatively to the teleport exit's angle, but in the wrong direction (Boom-compat)";
|
||||||
|
3 = "Adjust relatively to the teleport exit's angle (Boom-fixed)";
|
||||||
|
}
|
||||||
|
}
|
||||||
arg3
|
arg3
|
||||||
{
|
{
|
||||||
title = "Keep rel. Height";
|
title = "Keep rel. Height";
|
||||||
|
|
|
@ -920,6 +920,7 @@
|
||||||
<Compile Include="Map\MapElementCollection.cs" />
|
<Compile Include="Map\MapElementCollection.cs" />
|
||||||
<Compile Include="Map\SplitLineBehavior.cs" />
|
<Compile Include="Map\SplitLineBehavior.cs" />
|
||||||
<Compile Include="Rendering\CommentType.cs" />
|
<Compile Include="Rendering\CommentType.cs" />
|
||||||
|
<Compile Include="Rendering\CustomTextLabel.cs" />
|
||||||
<Compile Include="Rendering\SurfaceBufferSet.cs" />
|
<Compile Include="Rendering\SurfaceBufferSet.cs" />
|
||||||
<Compile Include="Rendering\SurfaceEntry.cs" />
|
<Compile Include="Rendering\SurfaceEntry.cs" />
|
||||||
<Compile Include="Rendering\SurfaceEntryCollection.cs" />
|
<Compile Include="Rendering\SurfaceEntryCollection.cs" />
|
||||||
|
|
|
@ -144,8 +144,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3D ClosestOnPlane(Vector3D p)
|
public Vector3D ClosestOnPlane(Vector3D p)
|
||||||
{
|
{
|
||||||
float d = this.Distance(p);
|
return p - normal * this.Distance(p);
|
||||||
return p - normal * d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -171,6 +170,20 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
{
|
{
|
||||||
return new Plane(-normal, -offset);
|
return new Plane(-normal, -offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd. Addeed to make compiler a bit more happy...
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return base.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
//mxd. Addeed to make compiler a bit more happy...
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if(!(obj is Plane)) return false;
|
||||||
|
Plane other = (Plane)obj;
|
||||||
|
return (normal != other.normal) || (offset != other.offset);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -2255,6 +2255,175 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd. Try to create/remove/reassign outer sidedefs. Selected linedefs and verts are marked
|
||||||
|
public static void AdjustOuterSidedefs(HashSet<Sector> selectedsectors, ICollection<Linedef> selectedlines)
|
||||||
|
{
|
||||||
|
HashSet<Sidedef> outersides = new HashSet<Sidedef>();
|
||||||
|
HashSet<Linedef> singlesidedlines = new HashSet<Linedef>();
|
||||||
|
HashSet<Linedef> lineswithoutsides = new HashSet<Linedef>();
|
||||||
|
|
||||||
|
// Collect lines without sidedefs and lines, which don't reference selected sectors
|
||||||
|
foreach(Linedef line in selectedlines)
|
||||||
|
{
|
||||||
|
if(line.Front == null && line.Back == null)
|
||||||
|
{
|
||||||
|
lineswithoutsides.Add(line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(line.Back != null && line.Back.Sector != null && !selectedsectors.Contains(line.Back.Sector))
|
||||||
|
outersides.Add(line.Back);
|
||||||
|
if(line.Front != null && line.Front.Sector != null && !selectedsectors.Contains(line.Front.Sector))
|
||||||
|
outersides.Add(line.Front);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect outer sides and single-sided lines
|
||||||
|
foreach(Sector sector in selectedsectors)
|
||||||
|
{
|
||||||
|
foreach(Sidedef side in sector.Sidedefs)
|
||||||
|
{
|
||||||
|
if(side.Other == null) singlesidedlines.Add(side.Line);
|
||||||
|
else if(!selectedsectors.Contains(side.Other.Sector)) outersides.Add(side.Other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check lines without sidedefs. Add new sidedefs if necessary
|
||||||
|
foreach(Linedef line in lineswithoutsides)
|
||||||
|
{
|
||||||
|
bool sideschanged = false;
|
||||||
|
|
||||||
|
// Add front side?
|
||||||
|
Vector2D testpoint = line.GetSidePoint(true);
|
||||||
|
Linedef nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
||||||
|
if(nl != null)
|
||||||
|
{
|
||||||
|
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||||
|
if(ns != null)
|
||||||
|
{
|
||||||
|
// Create new sidedef
|
||||||
|
Sidedef newside = General.Map.Map.CreateSidedef(line, true, ns.Sector);
|
||||||
|
|
||||||
|
// Copy props from the other side
|
||||||
|
ns.CopyPropertiesTo(newside);
|
||||||
|
newside.RemoveUnneededTextures(true, true, true);
|
||||||
|
|
||||||
|
sideschanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add back side?
|
||||||
|
testpoint = line.GetSidePoint(false);
|
||||||
|
nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
||||||
|
if(nl != null)
|
||||||
|
{
|
||||||
|
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||||
|
if(ns != null)
|
||||||
|
{
|
||||||
|
// Create new sidedef
|
||||||
|
Sidedef newside = General.Map.Map.CreateSidedef(line, false, ns.Sector);
|
||||||
|
|
||||||
|
// Copy props from the other side
|
||||||
|
ns.CopyPropertiesTo(newside);
|
||||||
|
newside.RemoveUnneededTextures(true, true, true);
|
||||||
|
|
||||||
|
sideschanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct the sided flags
|
||||||
|
if(sideschanged)
|
||||||
|
{
|
||||||
|
// Correct the linedef
|
||||||
|
if((line.Front == null) && (line.Back != null))
|
||||||
|
{
|
||||||
|
line.FlipVertices();
|
||||||
|
line.FlipSidedefs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct the sided flags
|
||||||
|
line.ApplySidedFlags();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check single-sided lines. Add new sidedefs if necessary
|
||||||
|
foreach(Linedef line in singlesidedlines)
|
||||||
|
{
|
||||||
|
// Line is now inside a sector?
|
||||||
|
Vector2D testpoint = line.GetSidePoint(line.Front == null);
|
||||||
|
Linedef nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
||||||
|
if(nl != null)
|
||||||
|
{
|
||||||
|
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||||
|
if(ns != null)
|
||||||
|
{
|
||||||
|
// Create new sidedef
|
||||||
|
Sidedef newside = General.Map.Map.CreateSidedef(line, line.Front == null, ns.Sector);
|
||||||
|
|
||||||
|
// Copy props from the other side
|
||||||
|
Sidedef propssource = ((line.Front ?? line.Back) ?? ns);
|
||||||
|
propssource.CopyPropertiesTo(newside);
|
||||||
|
newside.RemoveUnneededTextures(true, true, true);
|
||||||
|
newside.Other.RemoveUnneededTextures(true, true, true);
|
||||||
|
|
||||||
|
// Correct the linedef
|
||||||
|
if((line.Front == null) && (line.Back != null))
|
||||||
|
{
|
||||||
|
line.FlipVertices();
|
||||||
|
line.FlipSidedefs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct the sided flags
|
||||||
|
line.ApplySidedFlags();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check outer sidedefs. Remove/change sector if necessary
|
||||||
|
foreach(Sidedef side in outersides)
|
||||||
|
{
|
||||||
|
// Side is inside a sector?
|
||||||
|
Vector2D testpoint = side.Line.GetSidePoint(side.IsFront);
|
||||||
|
Linedef nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
||||||
|
bool lineisoutside = true;
|
||||||
|
if(nl != null)
|
||||||
|
{
|
||||||
|
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||||
|
if(ns != null)
|
||||||
|
{
|
||||||
|
lineisoutside = false;
|
||||||
|
if(ns.Sector != null && side.Sector != ns.Sector)
|
||||||
|
{
|
||||||
|
// Reattach side
|
||||||
|
side.SetSector(ns.Sector);
|
||||||
|
side.RemoveUnneededTextures(true, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Side points nowhere. Remove it
|
||||||
|
if(lineisoutside)
|
||||||
|
{
|
||||||
|
// Remove the sidedef
|
||||||
|
Linedef l = side.Line;
|
||||||
|
side.Dispose();
|
||||||
|
|
||||||
|
// Correct the linedef
|
||||||
|
if((l.Front == null) && (l.Back != null))
|
||||||
|
{
|
||||||
|
l.FlipVertices();
|
||||||
|
l.FlipSidedefs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct the sided flags
|
||||||
|
l.ApplySidedFlags();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update map geometry
|
||||||
|
General.Map.Map.Update();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Misc Exported Functions
|
#region ================== Misc Exported Functions
|
||||||
|
|
|
@ -2589,7 +2589,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>mxd. This finds the line closest to the specified position excluding given list of linedefs.</summary>
|
/// <summary>mxd. This finds the line closest to the specified position excluding given list of linedefs.</summary>
|
||||||
public Linedef NearestLinedef(Vector2D pos, List<Linedef> linesToExclude)
|
public Linedef NearestLinedef(Vector2D pos, ICollection<Linedef> linesToExclude)
|
||||||
{
|
{
|
||||||
Linedef closest = null;
|
Linedef closest = null;
|
||||||
float distance = float.MaxValue;
|
float distance = float.MaxValue;
|
||||||
|
@ -3113,6 +3113,38 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd
|
||||||
|
/// <summary>Gets unselected sectors, which have all their linedefs selected</summary>
|
||||||
|
public HashSet<Sector> GetUnselectedSectorsFromLinedefs(IEnumerable<Linedef> lines)
|
||||||
|
{
|
||||||
|
HashSet<Sector> result = new HashSet<Sector>();
|
||||||
|
Dictionary<Sector, HashSet<Sidedef>> sectorsbysides = new Dictionary<Sector, HashSet<Sidedef>>();
|
||||||
|
HashSet<Sector> selectedsectors = new HashSet<Sector>(General.Map.Map.GetSelectedSectors(true));
|
||||||
|
|
||||||
|
// Collect unselected sectors, which sidedefs belong to selected lines
|
||||||
|
foreach(Linedef line in lines)
|
||||||
|
{
|
||||||
|
if(line.Front != null && line.Front.Sector != null && !selectedsectors.Contains(line.Front.Sector))
|
||||||
|
{
|
||||||
|
if(!sectorsbysides.ContainsKey(line.Front.Sector)) sectorsbysides.Add(line.Front.Sector, new HashSet<Sidedef>());
|
||||||
|
sectorsbysides[line.Front.Sector].Add(line.Front);
|
||||||
|
}
|
||||||
|
if(line.Back != null && line.Back.Sector != null && !selectedsectors.Contains(line.Back.Sector))
|
||||||
|
{
|
||||||
|
if(!sectorsbysides.ContainsKey(line.Back.Sector)) sectorsbysides.Add(line.Back.Sector, new HashSet<Sidedef>());
|
||||||
|
sectorsbysides[line.Back.Sector].Add(line.Back);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add sectors, which have all their lines selected
|
||||||
|
foreach(var group in sectorsbysides)
|
||||||
|
{
|
||||||
|
if(group.Key.Sidedefs.Count == group.Value.Count) result.Add(group.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>This finds the line closest to the specified position.</summary>
|
/// <summary>This finds the line closest to the specified position.</summary>
|
||||||
public Linedef NearestLinedef(Vector2D pos) { return MapSet.NearestLinedef(linedefs, pos); }
|
public Linedef NearestLinedef(Vector2D pos) { return MapSet.NearestLinedef(linedefs, pos); }
|
||||||
|
|
||||||
|
|
30
Source/Core/Rendering/CustomTextLabel.cs
Normal file
30
Source/Core/Rendering/CustomTextLabel.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
using System.Drawing;
|
||||||
|
using SlimDX.Direct3D9;
|
||||||
|
using Font = System.Drawing.Font;
|
||||||
|
|
||||||
|
namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
{
|
||||||
|
//mxd. TextLabel wrapper
|
||||||
|
public abstract class CustomTextLabel : ITextLabel
|
||||||
|
{
|
||||||
|
protected TextLabel label; // Derived classes must create this!
|
||||||
|
|
||||||
|
// Required to render text label
|
||||||
|
public bool SkipRendering { get { return label.SkipRendering; } }
|
||||||
|
public Texture Texture { get { return label.Texture; } }
|
||||||
|
public VertexBuffer VertexBuffer { get { return label.VertexBuffer; } }
|
||||||
|
public Font Font { get { return label.Font; } set { label.Font = value; } }
|
||||||
|
public string Text { get { return label.Text; } set { label.Text = value; } }
|
||||||
|
|
||||||
|
// Access/setup
|
||||||
|
public TextLabel TextLabel { get { return label; } }
|
||||||
|
public PixelColor Color { get { return label.Color; } set { label.Color = value; } }
|
||||||
|
public PixelColor BackColor { get { return label.BackColor; } set { label.BackColor = value; } }
|
||||||
|
public SizeF TextSize { get { return label.TextSize; } }
|
||||||
|
|
||||||
|
public void Update(float translatex, float translatey, float scalex, float scaley)
|
||||||
|
{
|
||||||
|
label.Update(translatex, translatey, scalex, scaley);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,8 +74,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
void RenderLine(Vector2D start, Vector2D end, float thickness, PixelColor c, bool transformcoords);
|
void RenderLine(Vector2D start, Vector2D end, float thickness, PixelColor c, bool transformcoords);
|
||||||
void RenderArrows(ICollection<Line3D> line); //mxd
|
void RenderArrows(ICollection<Line3D> line); //mxd
|
||||||
void RenderArrows(ICollection<Line3D> line, bool transformcoords); //mxd
|
void RenderArrows(ICollection<Line3D> line, bool transformcoords); //mxd
|
||||||
void RenderText(TextLabel text);
|
void RenderText(ITextLabel text);
|
||||||
void RenderText(List<TextLabel> labels); //mxd
|
void RenderText(IList<ITextLabel> labels); //mxd
|
||||||
void RenderGeometry(FlatVertex[] vertices, ImageData texture, bool transformcoords);
|
void RenderGeometry(FlatVertex[] vertices, ImageData texture, bool transformcoords);
|
||||||
void RenderHighlight(FlatVertex[] vertices, int color); //mxd
|
void RenderHighlight(FlatVertex[] vertices, int color); //mxd
|
||||||
void RedrawSurface();
|
void RedrawSurface();
|
||||||
|
|
|
@ -1626,7 +1626,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
// This renders text
|
// This renders text
|
||||||
public void RenderText(TextLabel label)
|
public void RenderText(ITextLabel label)
|
||||||
{
|
{
|
||||||
//mxd. Update the text if needed
|
//mxd. Update the text if needed
|
||||||
label.Update(translatex, translatey, scale, -scale);
|
label.Update(translatex, translatey, scale, -scale);
|
||||||
|
@ -1653,11 +1653,11 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. This renders text
|
//mxd. This renders text
|
||||||
public void RenderText(List<TextLabel> labels)
|
public void RenderText(IList<ITextLabel> labels)
|
||||||
{
|
{
|
||||||
// Update labels
|
// Update labels
|
||||||
int skipped = 0;
|
int skipped = 0;
|
||||||
foreach(TextLabel label in labels)
|
foreach(ITextLabel label in labels)
|
||||||
{
|
{
|
||||||
// Update the text if needed
|
// Update the text if needed
|
||||||
label.Update(translatex, translatey, scale, -scale);
|
label.Update(translatex, translatey, scale, -scale);
|
||||||
|
@ -1680,7 +1680,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
graphics.Shaders.Display2D.Begin();
|
graphics.Shaders.Display2D.Begin();
|
||||||
graphics.Shaders.Display2D.BeginPass(1);
|
graphics.Shaders.Display2D.BeginPass(1);
|
||||||
|
|
||||||
foreach(TextLabel label in labels)
|
foreach(ITextLabel label in labels)
|
||||||
{
|
{
|
||||||
// Text is created?
|
// Text is created?
|
||||||
if(!label.SkipRendering)
|
if(!label.SkipRendering)
|
||||||
|
|
|
@ -31,7 +31,23 @@ using Font = System.Drawing.Font;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.Rendering
|
namespace CodeImp.DoomBuilder.Rendering
|
||||||
{
|
{
|
||||||
public class TextLabel : IDisposable, ID3DResource
|
public interface ITextLabel //mxd. Methods and properties required to render a textlabel
|
||||||
|
{
|
||||||
|
// Required to render text label
|
||||||
|
bool SkipRendering { get; }
|
||||||
|
Texture Texture { get; }
|
||||||
|
VertexBuffer VertexBuffer { get; }
|
||||||
|
|
||||||
|
// Access/setup
|
||||||
|
Font Font { get; }
|
||||||
|
string Text { get; set; }
|
||||||
|
PixelColor Color { get; set; }
|
||||||
|
PixelColor BackColor { get; set; }
|
||||||
|
|
||||||
|
void Update(float translatex, float translatey, float scalex, float scaley);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TextLabel : IDisposable, ID3DResource, ITextLabel
|
||||||
{
|
{
|
||||||
#region ================== Constants
|
#region ================== Constants
|
||||||
|
|
||||||
|
@ -90,9 +106,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
public PixelColor Color { get { return color; } set { if(!color.Equals(value)) { color = value; textureupdateneeded = true; } } }
|
public PixelColor Color { get { return color; } set { if(!color.Equals(value)) { color = value; textureupdateneeded = true; } } }
|
||||||
public PixelColor BackColor { get { return backcolor; } set { if(!backcolor.Equals(value)) { backcolor = value; textureupdateneeded = true; } } }
|
public PixelColor BackColor { get { return backcolor; } set { if(!backcolor.Equals(value)) { backcolor = value; textureupdateneeded = true; } } }
|
||||||
public bool DrawBackground { get { return drawbg; } set { if(drawbg != value) { drawbg = value; textureupdateneeded = true; } } } //mxd
|
public bool DrawBackground { get { return drawbg; } set { if(drawbg != value) { drawbg = value; textureupdateneeded = true; } } } //mxd
|
||||||
internal Texture Texture { get { return texture; } } //mxd
|
public Texture Texture { get { return texture; } } //mxd
|
||||||
internal VertexBuffer VertexBuffer { get { return textbuffer; } }
|
public VertexBuffer VertexBuffer { get { return textbuffer; } }
|
||||||
internal bool SkipRendering { get { return skiprendering; } } //mxd
|
public bool SkipRendering { get { return skiprendering; } } //mxd
|
||||||
|
|
||||||
// Disposing
|
// Disposing
|
||||||
public bool IsDisposed { get { return isdisposed; } }
|
public bool IsDisposed { get { return isdisposed; } }
|
||||||
|
@ -146,7 +162,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
#region ================== Methods
|
#region ================== Methods
|
||||||
|
|
||||||
// This updates the text if needed
|
// This updates the text if needed
|
||||||
internal void Update(float translatex, float translatey, float scalex, float scaley)
|
public void Update(float translatex, float translatey, float scalex, float scaley)
|
||||||
{
|
{
|
||||||
// Check if transformation changed and needs to be updated
|
// Check if transformation changed and needs to be updated
|
||||||
if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey ||
|
if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey ||
|
||||||
|
|
|
@ -111,6 +111,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// When not cancelled
|
// When not cancelled
|
||||||
if(!cancelled)
|
if(!cancelled)
|
||||||
{
|
{
|
||||||
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
|
if(unstablelines.Count == 0)
|
||||||
|
{
|
||||||
|
// Add sectors, which have all their linedefs selected
|
||||||
|
// (otherwise those would be destroyed after moving the selection)
|
||||||
|
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines);
|
||||||
|
|
||||||
|
// Process outer sidedefs
|
||||||
|
Tools.AdjustOuterSidedefs(toadjust, selectedlines);
|
||||||
|
}
|
||||||
|
|
||||||
// If only a single linedef was selected, deselect it now
|
// If only a single linedef was selected, deselect it now
|
||||||
if(selectedlines.Count == 1) General.Map.Map.ClearSelectedLinedefs();
|
if(selectedlines.Count == 1) General.Map.Map.ClearSelectedLinedefs();
|
||||||
}
|
}
|
||||||
|
@ -168,10 +179,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Redraw overlay
|
// Redraw overlay
|
||||||
if(renderer.StartOverlay(true))
|
if(renderer.StartOverlay(true))
|
||||||
{
|
{
|
||||||
foreach(LineLengthLabel l in labels)
|
renderer.RenderText(labels);
|
||||||
{
|
|
||||||
renderer.RenderText(l.TextLabel);
|
|
||||||
}
|
|
||||||
renderer.Finish();
|
renderer.Finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// When not cancelled
|
// When not cancelled
|
||||||
if(!cancelled)
|
if(!cancelled)
|
||||||
{
|
{
|
||||||
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
|
if(unstablelines.Count == 0)
|
||||||
|
{
|
||||||
|
HashSet<Sector> toadjust = new HashSet<Sector>(selectedsectors);
|
||||||
|
|
||||||
|
// Add sectors, which are not selected, but have all their linedefs selected
|
||||||
|
// (otherwise those would be destroyed after moving the selection)
|
||||||
|
toadjust.UnionWith(General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines));
|
||||||
|
|
||||||
|
// Process outer sidedefs
|
||||||
|
Tools.AdjustOuterSidedefs(toadjust, selectedlines);
|
||||||
|
}
|
||||||
|
|
||||||
// If only a single sector was selected, deselect it now
|
// If only a single sector was selected, deselect it now
|
||||||
if(selectedsectors.Count == 1)
|
if(selectedsectors.Count == 1)
|
||||||
{
|
{
|
||||||
|
@ -188,10 +201,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Redraw overlay
|
// Redraw overlay
|
||||||
if(renderer.StartOverlay(true))
|
if(renderer.StartOverlay(true))
|
||||||
{
|
{
|
||||||
foreach(LineLengthLabel l in labels)
|
renderer.RenderText(labels);
|
||||||
{
|
|
||||||
renderer.RenderText(l.TextLabel);
|
|
||||||
}
|
|
||||||
renderer.Finish();
|
renderer.Finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#region ================== Namespaces
|
#region ================== Namespaces
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using CodeImp.DoomBuilder.Map;
|
using CodeImp.DoomBuilder.Map;
|
||||||
using CodeImp.DoomBuilder.Rendering;
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
@ -53,7 +54,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
#region ================== Constructor / Disposer
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
// Constructor to start dragging immediately
|
// Constructor to start dragging immediately
|
||||||
public DragVerticesMode(Vertex dragitem, Vector2D dragstartmappos)
|
public DragVerticesMode(Vector2D dragstartmappos)
|
||||||
{
|
{
|
||||||
// Mark what we are dragging
|
// Mark what we are dragging
|
||||||
General.Map.Map.ClearAllMarks(false);
|
General.Map.Map.ClearAllMarks(false);
|
||||||
|
@ -97,6 +98,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// When not cancelled
|
// When not cancelled
|
||||||
if(!cancelled)
|
if(!cancelled)
|
||||||
{
|
{
|
||||||
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
|
if(selectedverts.Count > 1 && unstablelines.Count == 0)
|
||||||
|
{
|
||||||
|
// Add sectors, which have all their linedefs selected
|
||||||
|
// (otherwise those would be destroyed after moving the selection)
|
||||||
|
ICollection<Linedef> selectedlines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
|
||||||
|
HashSet<Sector> toadjust = General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines);
|
||||||
|
|
||||||
|
// Process outer sidedefs
|
||||||
|
Tools.AdjustOuterSidedefs(toadjust, selectedlines);
|
||||||
|
}
|
||||||
|
|
||||||
// If only a single vertex was selected, deselect it now
|
// If only a single vertex was selected, deselect it now
|
||||||
if(selectedverts.Count == 1) General.Map.Map.ClearSelectedVertices();
|
if(selectedverts.Count == 1) General.Map.Map.ClearSelectedVertices();
|
||||||
}
|
}
|
||||||
|
@ -156,10 +169,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Redraw overlay
|
// Redraw overlay
|
||||||
if(renderer.StartOverlay(true))
|
if(renderer.StartOverlay(true))
|
||||||
{
|
{
|
||||||
foreach(LineLengthLabel l in labels)
|
renderer.RenderText(labels);
|
||||||
{
|
|
||||||
renderer.RenderText(l.TextLabel);
|
|
||||||
}
|
|
||||||
renderer.Finish();
|
renderer.Finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,8 +140,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Render vertex at cursor
|
// Render vertex at cursor
|
||||||
renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
||||||
|
|
||||||
// Go for all labels
|
// Render labels
|
||||||
foreach(LineLengthLabel l in labels) renderer.RenderText(l.TextLabel);
|
renderer.RenderText(labels.ToArray());
|
||||||
|
|
||||||
//Render info label
|
//Render info label
|
||||||
Vector2D start = new Vector2D(mousemappos.x + (32 / renderer.Scale), mousemappos.y - (16 / renderer.Scale));
|
Vector2D start = new Vector2D(mousemappos.x + (32 / renderer.Scale), mousemappos.y - (16 / renderer.Scale));
|
||||||
|
|
|
@ -262,10 +262,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Render guide labels?
|
//mxd. Render guide labels?
|
||||||
if(renderguidelabels)
|
if(renderguidelabels) renderer.RenderText(guidelabels);
|
||||||
{
|
|
||||||
foreach(LineLengthLabel l in guidelabels) renderer.RenderText(l.TextLabel);
|
// Render labels
|
||||||
}
|
renderer.RenderText(labels.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine point color
|
// Determine point color
|
||||||
|
@ -274,9 +274,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Render vertex at cursor
|
// Render vertex at cursor
|
||||||
renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
||||||
|
|
||||||
// Go for all labels
|
|
||||||
foreach(LineLengthLabel l in labels) renderer.RenderText(l.TextLabel);
|
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
renderer.Finish();
|
renderer.Finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using CodeImp.DoomBuilder.Actions;
|
using CodeImp.DoomBuilder.Actions;
|
||||||
|
@ -160,6 +161,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
private List<float> thingangle;
|
private List<float> thingangle;
|
||||||
private ICollection<Vertex> unselectedvertices;
|
private ICollection<Vertex> unselectedvertices;
|
||||||
private ICollection<Linedef> unselectedlines;
|
private ICollection<Linedef> unselectedlines;
|
||||||
|
private ICollection<Linedef> unstablelines; //mxd
|
||||||
|
|
||||||
// Modification
|
// Modification
|
||||||
private float rotation;
|
private float rotation;
|
||||||
|
@ -1088,6 +1090,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
foreach(Linedef l in markedlines) l.Selected = true;
|
foreach(Linedef l in markedlines) l.Selected = true;
|
||||||
selectedlines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
|
selectedlines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
|
||||||
unselectedlines = General.Map.Map.LinedefsFromMarkedVertices(true, false, false);
|
unselectedlines = General.Map.Map.LinedefsFromMarkedVertices(true, false, false);
|
||||||
|
unstablelines = (pasting ? new Collection<Linedef>() : General.Map.Map.LinedefsFromMarkedVertices(false, false, true)); //mxd
|
||||||
|
|
||||||
// Array to keep original coordinates
|
// Array to keep original coordinates
|
||||||
vertexpos = new List<Vector2D>(selectedvertices.Count);
|
vertexpos = new List<Vector2D>(selectedvertices.Count);
|
||||||
|
@ -1475,7 +1478,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Remove any virtual sectors
|
// Remove any virtual sectors
|
||||||
General.Map.Map.RemoveVirtualSectors();
|
General.Map.Map.RemoveVirtualSectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
|
if(unstablelines.Count == 0)
|
||||||
|
{
|
||||||
|
// Update outer sides of the selection
|
||||||
|
HashSet<Sector> affectedsectors = new HashSet<Sector>(General.Map.Map.GetSelectedSectors(true));
|
||||||
|
affectedsectors.UnionWith(General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines));
|
||||||
|
Tools.AdjustOuterSidedefs(affectedsectors, selectedlines);
|
||||||
|
}
|
||||||
|
|
||||||
// Stitch geometry
|
// Stitch geometry
|
||||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
if(snaptonearest) General.Map.Map.StitchGeometry();
|
||||||
|
|
||||||
|
|
|
@ -633,7 +633,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd. Render sector tag labels
|
//mxd. Render sector tag labels
|
||||||
if(BuilderPlug.Me.ViewSelectionEffects)
|
if(BuilderPlug.Me.ViewSelectionEffects)
|
||||||
{
|
{
|
||||||
List<TextLabel> torender = new List<TextLabel>(sectorlabels.Count);
|
List<ITextLabel> torender = new List<ITextLabel>(sectorlabels.Count);
|
||||||
foreach(KeyValuePair<Sector, string[]> group in sectortexts)
|
foreach(KeyValuePair<Sector, string[]> group in sectortexts)
|
||||||
{
|
{
|
||||||
// Pick which text variant to use
|
// Pick which text variant to use
|
||||||
|
@ -668,7 +668,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd. Render selection labels
|
//mxd. Render selection labels
|
||||||
if(BuilderPlug.Me.ViewSelectionNumbers)
|
if(BuilderPlug.Me.ViewSelectionNumbers)
|
||||||
{
|
{
|
||||||
List<TextLabel> torender = new List<TextLabel>(labels.Count);
|
List<ITextLabel> torender = new List<ITextLabel>(labels.Count);
|
||||||
foreach(KeyValuePair<Linedef, SelectionLabel> group in labels)
|
foreach(KeyValuePair<Linedef, SelectionLabel> group in labels)
|
||||||
{
|
{
|
||||||
// Render only when enough space for the label to see
|
// Render only when enough space for the label to see
|
||||||
|
|
|
@ -193,7 +193,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
if(BuilderPlug.Me.ViewSelectionNumbers && orderedselection.Count < MAX_SECTOR_LABELS)
|
if(BuilderPlug.Me.ViewSelectionNumbers && orderedselection.Count < MAX_SECTOR_LABELS)
|
||||||
{
|
{
|
||||||
List<TextLabel> torender = new List<TextLabel>(orderedselection.Count);
|
List<ITextLabel> torender = new List<ITextLabel>(orderedselection.Count);
|
||||||
foreach(Sector s in orderedselection)
|
foreach(Sector s in orderedselection)
|
||||||
{
|
{
|
||||||
//mxd. Self-referencing (and probably some other) sectors don't have labels...
|
//mxd. Self-referencing (and probably some other) sectors don't have labels...
|
||||||
|
@ -225,7 +225,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd
|
//mxd
|
||||||
private void RenderEffectLabels(Dictionary<Sector, string[]> labelsGroup)
|
private void RenderEffectLabels(Dictionary<Sector, string[]> labelsGroup)
|
||||||
{
|
{
|
||||||
List<TextLabel> torender = new List<TextLabel>(labelsGroup.Count);
|
List<ITextLabel> torender = new List<ITextLabel>(labelsGroup.Count);
|
||||||
foreach(KeyValuePair<Sector, string[]> group in labelsGroup)
|
foreach(KeyValuePair<Sector, string[]> group in labelsGroup)
|
||||||
{
|
{
|
||||||
// Pick which text variant to use
|
// Pick which text variant to use
|
||||||
|
|
|
@ -266,7 +266,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd. Render sector tag labels
|
//mxd. Render sector tag labels
|
||||||
if(BuilderPlug.Me.ViewSelectionEffects && General.Map.FormatInterface.HasThingAction)
|
if(BuilderPlug.Me.ViewSelectionEffects && General.Map.FormatInterface.HasThingAction)
|
||||||
{
|
{
|
||||||
List<TextLabel> torender = new List<TextLabel>(sectorlabels.Count);
|
List<ITextLabel> torender = new List<ITextLabel>(sectorlabels.Count);
|
||||||
foreach(KeyValuePair<Sector, string[]> group in sectortexts)
|
foreach(KeyValuePair<Sector, string[]> group in sectortexts)
|
||||||
{
|
{
|
||||||
// Pick which text variant to use
|
// Pick which text variant to use
|
||||||
|
@ -301,7 +301,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd. Render selection labels
|
//mxd. Render selection labels
|
||||||
if(BuilderPlug.Me.ViewSelectionNumbers)
|
if(BuilderPlug.Me.ViewSelectionNumbers)
|
||||||
{
|
{
|
||||||
List<TextLabel> torender = new List<TextLabel>(labels.Count);
|
List<ITextLabel> torender = new List<ITextLabel>(labels.Count);
|
||||||
foreach(KeyValuePair<Thing, TextLabel> group in labels)
|
foreach(KeyValuePair<Thing, TextLabel> group in labels)
|
||||||
{
|
{
|
||||||
// Render only when enough space for the label to see
|
// Render only when enough space for the label to see
|
||||||
|
|
|
@ -586,7 +586,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Start dragging the selection
|
// Start dragging the selection
|
||||||
if(!BuilderPlug.Me.DontMoveGeometryOutsideMapBoundary || CanDrag()) //mxd
|
if(!BuilderPlug.Me.DontMoveGeometryOutsideMapBoundary || CanDrag()) //mxd
|
||||||
General.Editing.ChangeMode(new DragVerticesMode(highlighted, mousedownmappos));
|
General.Editing.ChangeMode(new DragVerticesMode(mousedownmappos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
{
|
{
|
||||||
public class HintLabel : LineLengthLabel
|
public class HintLabel : LineLengthLabel
|
||||||
{
|
{
|
||||||
public string Text { get { return label.Text; } set { label.Text = value; } }
|
|
||||||
|
|
||||||
public HintLabel() : base(false, false) { }
|
public HintLabel() : base(false, false) { }
|
||||||
public HintLabel(PixelColor textcolor) : base(false, false)
|
public HintLabel(PixelColor textcolor) : base(false, false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ using System.Drawing;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.BuilderModes
|
namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
{
|
{
|
||||||
public class LineLengthLabel : IDisposable
|
public class LineLengthLabel : CustomTextLabel, IDisposable
|
||||||
{
|
{
|
||||||
#region ================== Constants
|
#region ================== Constants
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
#region ================== Variables
|
#region ================== Variables
|
||||||
|
|
||||||
protected TextLabel label;
|
|
||||||
protected Vector2D start;
|
protected Vector2D start;
|
||||||
protected Vector2D end;
|
protected Vector2D end;
|
||||||
|
|
||||||
|
@ -47,14 +46,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
|
||||||
public TextLabel TextLabel { get { return label; } }
|
|
||||||
|
|
||||||
//mxd. Display options
|
//mxd. Display options
|
||||||
public bool ShowAngle { get { return showangle; } set { showangle = value; UpdateText(); } }
|
public bool ShowAngle { get { return showangle; } set { showangle = value; UpdateText(); } }
|
||||||
public bool OffsetPosition { get { return offsetposition; } set { offsetposition = value; Move(start, end); } }
|
public bool OffsetPosition { get { return offsetposition; } set { offsetposition = value; Move(start, end); } }
|
||||||
public PixelColor Color { get { return label.Color; } set { label.Color = value; } }
|
|
||||||
public PixelColor BackColor { get { return label.BackColor; } set { label.BackColor = value; } }
|
|
||||||
public SizeF TextSize { get { return label.TextSize; } }
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue