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:
MaxED 2016-04-25 14:48:39 +00:00
parent 5ab50fc981
commit 13aabd4257
21 changed files with 355 additions and 53 deletions

View file

@ -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";

View file

@ -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" />

View file

@ -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

View file

@ -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

View file

@ -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); }

View 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);
}
}
}

View file

@ -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();

View file

@ -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)

View file

@ -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 ||

View file

@ -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();
} }
} }

View file

@ -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();
} }
} }

View file

@ -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();
} }
} }

View file

@ -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));

View file

@ -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();
} }

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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));
} }
} }
} }

View file

@ -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)
{ {

View file

@ -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