lots of stuff (including half decent copy/paste)

This commit is contained in:
codeimp 2008-09-22 18:27:50 +00:00
parent fccba768f0
commit b1ccdbbc7f
29 changed files with 1692 additions and 1325 deletions

View file

@ -27,3 +27,5 @@
- Make Plugin Development Kit - Make Plugin Development Kit
- Add proper XML comments to classes, properties and methods - Add proper XML comments to classes, properties and methods
- Contact AlysiumX (AlysiumX@gmail.com) for official video tutorials
(see http://www.youtube.com/view_play_list?p=6FDD1F9F674419E8)

View file

@ -33,6 +33,7 @@
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ClassicModes\BaseClassicMode.cs" />
<Compile Include="ClassicModes\BrightnessMode.cs" /> <Compile Include="ClassicModes\BrightnessMode.cs" />
<Compile Include="ClassicModes\EditSelectionMode.cs" /> <Compile Include="ClassicModes\EditSelectionMode.cs" />
<Compile Include="ClassicModes\CurveLinedefsMode.cs" /> <Compile Include="ClassicModes\CurveLinedefsMode.cs" />

View file

@ -0,0 +1,107 @@
#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 System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Types;
using CodeImp.DoomBuilder.Config;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
public abstract class BaseClassicMode : ClassicMode
{
#region ================== Constants
#endregion
#region ================== Variables
#endregion
#region ================== Properties
#endregion
#region ================== Constructor / Disposer
// Constructor
public BaseClassicMode()
{
// Initialize
// We have no destructor
GC.SuppressFinalize(this);
}
// Disposer
public override void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
// Done
base.Dispose();
}
}
#endregion
#region ================== Methods
// This occurs when the user presses Copy. All selected geometry must be marked for copying!
public override bool OnCopyBegin()
{
General.Map.Map.MarkAllSelectedGeometry(true);
// Return true when anything is selected so that the copy continues
// We only have to check vertices for the geometry, because without selected
// vertices, no complete structure can exist.
return (General.Map.Map.GetMarkedVertices(true).Count > 0) ||
(General.Map.Map.GetMarkedThings(true).Count > 0);
}
// This is called when something is pasted.
public override void OnPasteEnd()
{
General.Map.Map.ClearAllSelected();
General.Map.Map.SelectMarkedGeometry(true, true);
// Switch to EditSelectionMode
General.Map.ChangeMode("EditSelectionMode");
}
#endregion
}
}

View file

@ -38,7 +38,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
[EditMode(DisplayName = "Curve Linedefs", [EditMode(DisplayName = "Curve Linedefs",
Volatile = true)] Volatile = true)]
public sealed class CurveLinedefsMode : ClassicMode public sealed class CurveLinedefsMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -48,9 +48,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables #region ================== Variables
// Mode to return to
private EditMode basemode;
// Collections // Collections
private ICollection<Linedef> selectedlines; private ICollection<Linedef> selectedlines;
private ICollection<Linedef> unselectedlines; private ICollection<Linedef> unselectedlines;
@ -60,9 +57,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties #region ================== Properties
// Just keep the base mode button checked // Just keep the base mode button checked
public override string EditModeButtonName { get { return basemode.GetType().Name; } } public override string EditModeButtonName { get { return General.Map.PreviousStableMode.Name; } }
internal EditMode BaseMode { get { return basemode; } }
#endregion #endregion
@ -71,8 +66,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Constructor // Constructor
public CurveLinedefsMode(EditMode basemode) public CurveLinedefsMode(EditMode basemode)
{ {
this.basemode = basemode;
// Make collections by selection // Make collections by selection
selectedlines = General.Map.Map.GetSelectedLinedefs(true); selectedlines = General.Map.Map.GetSelectedLinedefs(true);
unselectedlines = General.Map.Map.GetSelectedLinedefs(false); unselectedlines = General.Map.Map.GetSelectedLinedefs(false);
@ -95,6 +88,73 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Methods #region ================== Methods
// This generates the vertices to split the line with, from start to end
private List<Vector2D> GenerateCurve(Linedef line)
{
// Fetch settings from window
int vertices = BuilderPlug.Me.CurveLinedefsForm.Vertices;
float distance = BuilderPlug.Me.CurveLinedefsForm.Distance;
float angle = BuilderPlug.Me.CurveLinedefsForm.Angle;
bool fixedcurve = BuilderPlug.Me.CurveLinedefsForm.FixedCurve;
bool backwards = BuilderPlug.Me.CurveLinedefsForm.Backwards;
// Make list
List<Vector2D> points = new List<Vector2D>(vertices);
//Added by Anders Åstrand 2008-05-18
//The formulas used are taken from http://mathworld.wolfram.com/CircularSegment.html
//c and theta are known (length of line and angle parameter). d, R and h are
//calculated from those two
//If the curve is not supposed to be a circular segment it's simply deformed to fit
//the value set for distance.
//The vertices are generated to be evenly distributed (by angle) along the curve
//and lastly they are rotated and moved to fit with the original line
//calculate some identities of a circle segment (refer to the graph in the url above)
double c = line.Length;
double theta = angle;
double d = (c / Math.Tan(theta / 2)) / 2;
double R = d / Math.Cos(theta / 2);
double h = R - d;
double yDeform = fixedcurve ? 1 : distance / h;
if(backwards)
yDeform = -yDeform;
double a, x, y;
Vector2D vertex;
for(int v = 1; v <= vertices; v++)
{
//calculate the angle for this vertex
//the curve starts at PI/2 - theta/2 and is segmented into vertices+1 segments
//this assumes the line is horisontal and on y = 0, the point is rotated and moved later
a = (Math.PI - theta) / 2 + v * (theta / (vertices + 1));
//calculate the coordinates of the point, and distort the y coordinate
//using the deform factor calculated above
x = Math.Cos(a) * R;
y = (Math.Sin(a) * R - d) * yDeform;
//rotate and transform to fit original line
vertex = new Vector2D((float)x, (float)y).GetRotated(line.Angle + Angle2D.PIHALF);
vertex = vertex.GetTransformed(line.GetCenterPoint().x, line.GetCenterPoint().y, 1, 1);
points.Add(vertex);
}
// Done
return points;
}
#endregion
#region ================== Events
// Cancelled // Cancelled
public override void OnCancel() public override void OnCancel()
{ {
@ -102,7 +162,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel(); base.OnCancel();
// Return to base mode // Return to base mode
General.Map.ChangeMode(basemode); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
} }
// Mode engages // Mode engages
@ -161,70 +221,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.IsChanged = true; General.Map.IsChanged = true;
// Return to base mode // Return to base mode
General.Map.ChangeMode(basemode); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// This generates the vertices to split the line with, from start to end
private List<Vector2D> GenerateCurve(Linedef line)
{
// Fetch settings from window
int vertices = BuilderPlug.Me.CurveLinedefsForm.Vertices;
float distance = BuilderPlug.Me.CurveLinedefsForm.Distance;
float angle = BuilderPlug.Me.CurveLinedefsForm.Angle;
bool fixedcurve = BuilderPlug.Me.CurveLinedefsForm.FixedCurve;
bool backwards = BuilderPlug.Me.CurveLinedefsForm.Backwards;
// Make list
List<Vector2D> points = new List<Vector2D>(vertices);
//Added by Anders Åstrand 2008-05-18
//The formulas used are taken from http://mathworld.wolfram.com/CircularSegment.html
//c and theta are known (length of line and angle parameter). d, R and h are
//calculated from those two
//If the curve is not supposed to be a circular segment it's simply deformed to fit
//the value set for distance.
//The vertices are generated to be evenly distributed (by angle) along the curve
//and lastly they are rotated and moved to fit with the original line
//calculate some identities of a circle segment (refer to the graph in the url above)
double c = line.Length;
double theta = angle;
double d = (c / Math.Tan(theta / 2)) / 2;
double R = d / Math.Cos(theta / 2);
double h = R - d;
double yDeform = fixedcurve ? 1 : distance / h;
if (backwards)
yDeform = -yDeform;
double a, x, y;
Vector2D vertex;
for (int v = 1; v <= vertices; v++)
{
//calculate the angle for this vertex
//the curve starts at PI/2 - theta/2 and is segmented into vertices+1 segments
//this assumes the line is horisontal and on y = 0, the point is rotated and moved later
a = (Math.PI - theta)/2 + v * (theta / (vertices + 1));
//calculate the coordinates of the point, and distort the y coordinate
//using the deform factor calculated above
x = Math.Cos(a) * R;
y = (Math.Sin(a) * R - d) * yDeform;
//rotate and transform to fit original line
vertex = new Vector2D((float)x, (float)y).GetRotated(line.Angle + Angle2D.PIHALF);
vertex = vertex.GetTransformed(line.GetCenterPoint().x, line.GetCenterPoint().y, 1, 1);
points.Add(vertex);
}
// Done
return points;
} }
// Redrawing display // Redrawing display

View file

@ -36,7 +36,7 @@ using CodeImp.DoomBuilder.Editing;
namespace CodeImp.DoomBuilder.BuilderModes namespace CodeImp.DoomBuilder.BuilderModes
{ {
public abstract class DragGeometryMode : ClassicMode public abstract class DragGeometryMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -44,9 +44,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables #region ================== Variables
// Mode to return to
private EditMode basemode;
// Mouse position on map where dragging started // Mouse position on map where dragging started
private Vector2D dragstartmappos; private Vector2D dragstartmappos;
@ -86,9 +83,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties #region ================== Properties
// Just keep the base mode button checked // Just keep the base mode button checked
public override string EditModeButtonName { get { return basemode.GetType().Name; } } public override string EditModeButtonName { get { return General.Map.PreviousStableMode.Name; } }
internal EditMode BaseMode { get { return basemode; } }
#endregion #endregion
@ -119,9 +114,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Initialize // Initialize
this.dragstartmappos = dragstartmappos; this.dragstartmappos = dragstartmappos;
// Create new instance of the previous mode
this.basemode = (EditMode)Assembly.GetCallingAssembly().CreateInstance(General.Map.Mode.GetType().FullName, false, BindingFlags.Default, null, null, CultureInfo.CurrentCulture, new object[0]);
Cursor.Current = Cursors.AppStarting; Cursor.Current = Cursors.AppStarting;
// Make list of selected vertices // Make list of selected vertices
@ -291,7 +283,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel(); base.OnCancel();
// Return to vertices mode // Return to vertices mode
General.Map.ChangeMode(basemode); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
} }
// Mode engages // Mode engages
@ -375,7 +367,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
protected override void OnEndEdit() protected override void OnEndEdit()
{ {
// Just return to base mode, Disengage will be called automatically. // Just return to base mode, Disengage will be called automatically.
General.Map.ChangeMode(basemode); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
base.OnEndEdit(); base.OnEndEdit();
} }

View file

@ -68,7 +68,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DragLinedefsMode(Vector2D dragstartmappos) public DragLinedefsMode(Vector2D dragstartmappos)
{ {
// Mark what we are dragging // Mark what we are dragging
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedLinedefs(true, true); General.Map.Map.MarkSelectedLinedefs(true, true);
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true); ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
foreach(Vertex v in verts) v.Marked = true; foreach(Vertex v in verts) v.Marked = true;

View file

@ -68,7 +68,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DragSectorsMode(Vector2D dragstartmappos) public DragSectorsMode(Vector2D dragstartmappos)
{ {
// Mark what we are dragging // Mark what we are dragging
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedLinedefs(true, true); General.Map.Map.MarkSelectedLinedefs(true, true);
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true); ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
foreach(Vertex v in verts) v.Marked = true; foreach(Vertex v in verts) v.Marked = true;

View file

@ -45,7 +45,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
[EditMode(DisplayName = "Things", [EditMode(DisplayName = "Things",
Volatile = true)] Volatile = true)]
public sealed class DragThingsMode : ClassicMode public sealed class DragThingsMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -104,7 +104,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Cursor.Current = Cursors.AppStarting; Cursor.Current = Cursors.AppStarting;
// Mark what we are dragging // Mark what we are dragging
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedThings(true, true); General.Map.Map.MarkSelectedThings(true, true);
// Get selected things // Get selected things

View file

@ -65,7 +65,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DragVerticesMode(Vertex dragitem, Vector2D dragstartmappos) public DragVerticesMode(Vertex dragitem, Vector2D dragstartmappos)
{ {
// Mark what we are dragging // Mark what we are dragging
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true); General.Map.Map.MarkSelectedVertices(true, true);
// Initialize // Initialize

View file

@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
SwitchAction = "drawlinesmode", SwitchAction = "drawlinesmode",
Volatile = true)] Volatile = true)]
public class DrawGeometryMode : ClassicMode public class DrawGeometryMode : BaseClassicMode
{ {
#region ================== Structures #region ================== Structures
@ -61,9 +61,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables #region ================== Variables
// Mode to return to
private EditMode basemode;
// Drawing points // Drawing points
private List<DrawnVertex> points; private List<DrawnVertex> points;
private List<LineLengthLabel> labels; private List<LineLengthLabel> labels;
@ -82,9 +79,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties #region ================== Properties
// Just keep the base mode button checked // Just keep the base mode button checked
public override string EditModeButtonName { get { return basemode.GetType().Name; } } public override string EditModeButtonName { get { return General.Map.PreviousStableMode.Name; } }
internal EditMode BaseMode { get { return basemode; } }
#endregion #endregion
@ -94,13 +89,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DrawGeometryMode() public DrawGeometryMode()
{ {
// Initialize // Initialize
this.basemode = General.Map.Mode;
points = new List<DrawnVertex>(); points = new List<DrawnVertex>();
labels = new List<LineLengthLabel>(); labels = new List<LineLengthLabel>();
// No selection in this mode // No selection in this mode
General.Map.Map.ClearAllSelected(); General.Map.Map.ClearAllSelected();
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
// We have no destructor // We have no destructor
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
@ -125,6 +119,215 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Methods #region ================== Methods
// This checks if the view offset/zoom changed and updates the check
protected bool CheckViewChanged()
{
bool viewchanged = false;
// View changed?
if(renderer.OffsetX != lastoffsetx) viewchanged = true;
if(renderer.OffsetY != lastoffsety) viewchanged = true;
if(renderer.Scale != lastscale) viewchanged = true;
// Keep view information
lastoffsetx = renderer.OffsetX;
lastoffsety = renderer.OffsetY;
lastscale = renderer.Scale;
// Return result
return viewchanged;
}
// This updates the dragging
private void Update()
{
PixelColor stitchcolor = General.Colors.Highlight;
PixelColor losecolor = General.Colors.Selection;
PixelColor color;
snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;
DrawnVertex lastp = new DrawnVertex();
DrawnVertex curp = GetCurrentPosition();
float vsize = ((float)renderer.VertexSize + 1.0f) / renderer.Scale;
float vsizeborder = ((float)renderer.VertexSize + 3.0f) / renderer.Scale;
// The last label's end must go to the mouse cursor
if(labels.Count > 0) labels[labels.Count - 1].End = curp.pos;
// Render drawing lines
if(renderer.StartOverlay(true))
{
// Go for all points to draw lines
if(points.Count > 0)
{
// Render lines
lastp = points[0];
for(int i = 1; i < points.Count; i++)
{
// Determine line color
if(lastp.stitch && points[i].stitch) color = stitchcolor;
else color = losecolor;
// Render line
renderer.RenderLine(lastp.pos, points[i].pos, LINE_THICKNESS, color, true);
lastp = points[i];
}
// Determine line color
if(lastp.stitch && snaptonearest) color = stitchcolor;
else color = losecolor;
// Render line to cursor
renderer.RenderLine(lastp.pos, curp.pos, LINE_THICKNESS, color, true);
// Render vertices
for(int i = 0; i < points.Count; i++)
{
// Determine line color
if(points[i].stitch) color = stitchcolor;
else color = losecolor;
// Render line
renderer.RenderRectangleFilled(new RectangleF(points[i].pos.x - vsize, points[i].pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
}
}
// Determine point color
if(snaptonearest) color = stitchcolor;
else color = losecolor;
// Render vertex at cursor
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
renderer.Finish();
}
// Done
renderer.Present();
}
// This gets the aligned and snapped draw position
private DrawnVertex GetCurrentPosition()
{
DrawnVertex p = new DrawnVertex();
// Snap to nearest?
if(snaptonearest)
{
float vrange = VerticesMode.VERTEX_HIGHLIGHT_RANGE / renderer.Scale;
// Go for all drawn points
foreach(DrawnVertex v in points)
{
Vector2D delta = mousemappos - v.pos;
if(delta.GetLengthSq() < (vrange * vrange))
{
p.pos = v.pos;
p.stitch = true;
return p;
}
}
// Try the nearest vertex
Vertex nv = General.Map.Map.NearestVertexSquareRange(mousemappos, vrange);
if(nv != null)
{
p.pos = nv.Position;
p.stitch = true;
return p;
}
// Try the nearest linedef
Linedef nl = General.Map.Map.NearestLinedefRange(mousemappos, LinedefsMode.LINEDEF_HIGHLIGHT_RANGE / renderer.Scale);
if(nl != null)
{
// Snap to grid?
if(snaptogrid)
{
// Get grid intersection coordinates
List<Vector2D> coords = nl.GetGridIntersections();
// Find nearest grid intersection
float found_distance = float.MaxValue;
Vector2D found_coord = new Vector2D();
foreach(Vector2D v in coords)
{
Vector2D delta = mousemappos - v;
if(delta.GetLengthSq() < found_distance)
{
found_distance = delta.GetLengthSq();
found_coord = v;
}
}
// Align to the closest grid intersection
p.pos = found_coord;
p.stitch = true;
return p;
}
else
{
// Aligned to line
p.pos = nl.NearestOnLine(mousemappos);
p.stitch = true;
return p;
}
}
}
// Snap to grid?
if(snaptogrid)
{
// Aligned to grid
p.pos = General.Map.Grid.SnappedToGrid(mousemappos);
p.stitch = snaptonearest;
return p;
}
else
{
// Normal position
p.pos = mousemappos;
p.stitch = snaptonearest;
return p;
}
}
// This draws a point at a specific location
public void DrawPointAt(Vector2D pos, bool stitch)
{
DrawnVertex newpoint = new DrawnVertex();
newpoint.pos = pos;
newpoint.stitch = stitch;
points.Add(newpoint);
labels.Add(new LineLengthLabel());
labels[labels.Count - 1].Start = newpoint.pos;
if(labels.Count > 1) labels[labels.Count - 2].End = newpoint.pos;
Update();
// Check if point stitches with the first
if((points.Count > 1) && (points[points.Count - 1].stitch))
{
Vector2D p1 = points[0].pos;
Vector2D p2 = points[points.Count - 1].pos;
Vector2D delta = p1 - p2;
if((Math.Abs(delta.x) <= 0.001f) && (Math.Abs(delta.y) <= 0.001f))
{
// Finish drawing
FinishDraw();
}
}
}
#endregion
#region ================== Events
// Engaging // Engaging
public override void OnEngage() public override void OnEngage()
{ {
@ -142,9 +345,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel(); base.OnCancel();
// Return to original mode // Return to original mode
Type t = basemode.GetType(); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
basemode = (EditMode)Activator.CreateInstance(t);
General.Map.ChangeMode(basemode);
} }
// Accepted // Accepted
@ -577,28 +778,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Cursor.Current = Cursors.Default; Cursor.Current = Cursors.Default;
// Return to original mode // Return to original mode
Type t = basemode.GetType(); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
basemode = (EditMode)Activator.CreateInstance(t);
General.Map.ChangeMode(basemode);
}
// This checks if the view offset/zoom changed and updates the check
protected bool CheckViewChanged()
{
bool viewchanged = false;
// View changed?
if(renderer.OffsetX != lastoffsetx) viewchanged = true;
if(renderer.OffsetY != lastoffsety) viewchanged = true;
if(renderer.Scale != lastscale) viewchanged = true;
// Keep view information
lastoffsetx = renderer.OffsetX;
lastoffsety = renderer.OffsetY;
lastscale = renderer.Scale;
// Return result
return viewchanged;
} }
// This redraws the display // This redraws the display
@ -623,166 +803,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
Update(); Update();
} }
// This updates the dragging
private void Update()
{
PixelColor stitchcolor = General.Colors.Highlight;
PixelColor losecolor = General.Colors.Selection;
PixelColor color;
snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;
DrawnVertex lastp = new DrawnVertex();
DrawnVertex curp = GetCurrentPosition();
float vsize = ((float)renderer.VertexSize + 1.0f) / renderer.Scale;
float vsizeborder = ((float)renderer.VertexSize + 3.0f) / renderer.Scale;
// The last label's end must go to the mouse cursor
if(labels.Count > 0) labels[labels.Count - 1].End = curp.pos;
// Render drawing lines
if(renderer.StartOverlay(true))
{
// Go for all points to draw lines
if(points.Count > 0)
{
// Render lines
lastp = points[0];
for(int i = 1; i < points.Count; i++)
{
// Determine line color
if(lastp.stitch && points[i].stitch) color = stitchcolor;
else color = losecolor;
// Render line
renderer.RenderLine(lastp.pos, points[i].pos, LINE_THICKNESS, color, true);
lastp = points[i];
}
// Determine line color
if(lastp.stitch && snaptonearest) color = stitchcolor;
else color = losecolor;
// Render line to cursor
renderer.RenderLine(lastp.pos, curp.pos, LINE_THICKNESS, color, true);
// Render vertices
for(int i = 0; i < points.Count; i++)
{
// Determine line color
if(points[i].stitch) color = stitchcolor;
else color = losecolor;
// Render line
renderer.RenderRectangleFilled(new RectangleF(points[i].pos.x - vsize, points[i].pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
}
}
// Determine point color
if(snaptonearest) color = stitchcolor;
else color = losecolor;
// Render vertex at cursor
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
renderer.Finish();
}
// Done
renderer.Present();
}
// This gets the aligned and snapped draw position
private DrawnVertex GetCurrentPosition()
{
DrawnVertex p = new DrawnVertex();
// Snap to nearest?
if(snaptonearest)
{
float vrange = VerticesMode.VERTEX_HIGHLIGHT_RANGE / renderer.Scale;
// Go for all drawn points
foreach(DrawnVertex v in points)
{
Vector2D delta = mousemappos - v.pos;
if(delta.GetLengthSq() < (vrange * vrange))
{
p.pos = v.pos;
p.stitch = true;
return p;
}
}
// Try the nearest vertex
Vertex nv = General.Map.Map.NearestVertexSquareRange(mousemappos, vrange);
if(nv != null)
{
p.pos = nv.Position;
p.stitch = true;
return p;
}
// Try the nearest linedef
Linedef nl = General.Map.Map.NearestLinedefRange(mousemappos, LinedefsMode.LINEDEF_HIGHLIGHT_RANGE / renderer.Scale);
if(nl != null)
{
// Snap to grid?
if(snaptogrid)
{
// Get grid intersection coordinates
List<Vector2D> coords = nl.GetGridIntersections();
// Find nearest grid intersection
float found_distance = float.MaxValue;
Vector2D found_coord = new Vector2D();
foreach(Vector2D v in coords)
{
Vector2D delta = mousemappos - v;
if(delta.GetLengthSq() < found_distance)
{
found_distance = delta.GetLengthSq();
found_coord = v;
}
}
// Align to the closest grid intersection
p.pos = found_coord;
p.stitch = true;
return p;
}
else
{
// Aligned to line
p.pos = nl.NearestOnLine(mousemappos);
p.stitch = true;
return p;
}
}
}
// Snap to grid?
if(snaptogrid)
{
// Aligned to grid
p.pos = General.Map.Grid.SnappedToGrid(mousemappos);
p.stitch = snaptonearest;
return p;
}
else
{
// Normal position
p.pos = mousemappos;
p.stitch = snaptonearest;
return p;
}
}
// Mouse moving // Mouse moving
public override void OnMouseMove(MouseEventArgs e) public override void OnMouseMove(MouseEventArgs e)
{ {
@ -790,32 +810,26 @@ namespace CodeImp.DoomBuilder.BuilderModes
Update(); Update();
} }
// This draws a point at a specific location // When a key is released
public void DrawPointAt(Vector2D pos, bool stitch) public override void OnKeyUp(KeyEventArgs e)
{ {
DrawnVertex newpoint = new DrawnVertex(); base.OnKeyUp(e);
newpoint.pos = pos; if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
newpoint.stitch = stitch; (snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
points.Add(newpoint); }
labels.Add(new LineLengthLabel());
labels[labels.Count - 1].Start = newpoint.pos;
if(labels.Count > 1) labels[labels.Count - 2].End = newpoint.pos;
Update();
// Check if point stitches with the first // When a key is pressed
if((points.Count > 1) && (points[points.Count - 1].stitch)) public override void OnKeyDown(KeyEventArgs e)
{ {
Vector2D p1 = points[0].pos; base.OnKeyDown(e);
Vector2D p2 = points[points.Count - 1].pos; if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
Vector2D delta = p1 - p2; (snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
if((Math.Abs(delta.x) <= 0.001f) && (Math.Abs(delta.y) <= 0.001f))
{
// Finish drawing
FinishDraw();
}
}
} }
#endregion
#region ================== Actions
// Drawing a point // Drawing a point
[BeginAction("drawpoint")] [BeginAction("drawpoint")]
public void DrawPoint() public void DrawPoint()
@ -850,22 +864,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.AcceptMode(); General.Map.AcceptMode();
} }
// When a key is released
public override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
}
// When a key is pressed
public override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
}
#endregion #endregion
} }
} }

View file

@ -43,7 +43,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
SwitchAction = "editselectionmode", // Action name used to switch to this mode SwitchAction = "editselectionmode", // Action name used to switch to this mode
Volatile = true)] Volatile = true)]
public class EditSelectionMode : ClassicMode public class EditSelectionMode : BaseClassicMode
{ {
#region ================== Enums #region ================== Enums
@ -83,8 +83,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables #region ================== Variables
// Mode to return to // Mode switching
private EditMode basemode;
private bool modealreadyswitching = false; private bool modealreadyswitching = false;
// Highlighted vertex // Highlighted vertex
@ -133,7 +132,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties #region ================== Properties
// Just keep the base mode button checked // Just keep the base mode button checked
public override string EditModeButtonName { get { return basemode.GetType().Name; } } public override string EditModeButtonName { get { return General.Map.PreviousStableMode.Name; } }
#endregion #endregion
@ -143,11 +142,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public EditSelectionMode() public EditSelectionMode()
{ {
// Initialize // Initialize
basemode = General.Map.Mode;
mode = ModifyMode.None; mode = ModifyMode.None;
// TEST:
rotation = Angle2D.PI2 * 0;// 0.02f;
} }
// Disposer // Disposer
@ -163,461 +158,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
#endregion
#region ================== Events
// Mode engages
public override void OnEngage()
{
base.OnEngage();
// Convert geometry selection
General.Map.Map.ClearAllMarks();
General.Map.Map.MarkSelectedVertices(true, true);
General.Map.Map.MarkSelectedThings(true, true);
General.Map.Map.MarkSelectedLinedefs(true, true);
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
foreach(Vertex v in verts) v.Marked = true;
selectedvertices = General.Map.Map.GetMarkedVertices(true);
selectedthings = General.Map.Map.GetMarkedThings(true);
unselectedvertices = General.Map.Map.GetMarkedVertices(false);
// Make sure everything is selected so that it turns up red
foreach(Vertex v in selectedvertices) v.Selected = true;
ICollection<Linedef> markedlines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in markedlines) l.Selected = true;
unselectedlines = General.Map.Map.LinedefsFromMarkedVertices(true, false, false);
// Array to keep original coordinates
vertexpos = new List<Vector2D>(selectedvertices.Count);
thingpos = new List<Vector2D>(selectedthings.Count);
// A selection must be made!
if((selectedvertices.Count > 0) || (selectedthings.Count > 0))
{
// Initialize offset and size
offset.x = float.MaxValue;
offset.y = float.MaxValue;
Vector2D right;
right.x = float.MinValue;
right.y = float.MinValue;
foreach(Vertex v in selectedvertices)
{
// Find left-top and right-bottom
if(v.Position.x < offset.x) offset.x = v.Position.x;
if(v.Position.y < offset.y) offset.y = v.Position.y;
if(v.Position.x > right.x) right.x = v.Position.x;
if(v.Position.y > right.y) right.y = v.Position.y;
// Keep original coordinates
vertexpos.Add(v.Position);
}
foreach(Thing t in selectedthings)
{
// Find left-top and right-bottom
if(t.Position.x < offset.x) offset.x = t.Position.x;
if(t.Position.y < offset.y) offset.y = t.Position.y;
if(t.Position.x > right.x) right.x = t.Position.x;
if(t.Position.y > right.y) right.y = t.Position.y;
// Keep original coordinates
thingpos.Add(t.Position);
}
// Calculate size
size = right - offset;
// If the width of a dimension is zero, add a little
if(Math.Abs(size.x) < 1.0f)
{
size.x += ZERO_SIZE_ADDITION;
offset.x -= ZERO_SIZE_ADDITION / 2;
}
if(Math.Abs(size.y) < 1.0f)
{
size.y += ZERO_SIZE_ADDITION;
offset.y -= ZERO_SIZE_ADDITION / 2;
}
basesize = size;
baseoffset = offset;
// Set presentation
if(selectedthings.Count > 0)
renderer.SetPresentation(Presentation.Things);
else
renderer.SetPresentation(Presentation.Standard);
// Update
UpdateRectangleComponents();
}
else
{
General.Interface.DisplayWarning("Please make a selection first!");
// Cancel now
General.Map.CancelMode();
}
}
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Reset geometry in original position
int index = 0;
foreach(Vertex v in selectedvertices)
v.Move(vertexpos[index++]);
index = 0;
foreach(Thing t in selectedthings)
t.Move(thingpos[index++]);
General.Map.Map.Update(true, true);
// Return to original mode
Type mt = basemode.GetType();
basemode = (EditMode)Activator.CreateInstance(mt);
General.Map.ChangeMode(basemode);
}
// When accepted
public override void OnAccept()
{
base.OnAccept();
// Anything to do?
if((selectedthings.Count > 0) || (selectedvertices.Count > 0))
{
Cursor.Current = Cursors.AppStarting;
// Reset geometry in original position
int index = 0;
foreach(Vertex v in selectedvertices)
v.Move(vertexpos[index++]);
index = 0;
foreach(Thing t in selectedthings)
t.Move(thingpos[index++]);
// Make undo
General.Map.UndoRedo.CreateUndo("Edit selection", UndoGroup.None, 0);
// Move geometry to new position
UpdateGeometry();
General.Map.Map.Update(true, true);
// Stitch geometry
if(snaptonearest) General.Map.Map.StitchGeometry();
// Snap to map format accuracy
General.Map.Map.SnapAllToAccuracy();
// Update cached values
General.Map.Map.Update();
// Done
selectedvertices = new List<Vertex>();
selectedthings = new List<Thing>();
Cursor.Current = Cursors.Default;
General.Map.IsChanged = true;
}
if(!modealreadyswitching)
{
// Return to original mode
Type mt = basemode.GetType();
basemode = (EditMode)Activator.CreateInstance(mt);
General.Map.ChangeMode(basemode);
}
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// When not cancelled manually, we assume it is accepted
if(!cancelled)
{
modealreadyswitching = true;
this.OnAccept();
}
// Hide highlight info
General.Interface.HideInfo();
General.Interface.SetCursor(Cursors.Default);
}
// This redraws the display
public override void OnRedrawDisplay()
{
UpdateRectangleComponents();
// Render lines
if(renderer.StartPlotter(true))
{
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
renderer.PlotVerticesSet(General.Map.Map.Vertices);
if(highlighted != null) renderer.PlotVertex(highlighted, ColorCollection.HIGHLIGHT);
renderer.Finish();
}
// Render things
if(renderer.StartThings(true))
{
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
renderer.Finish();
}
// Render selection
if(renderer.StartOverlay(true))
{
// Rectangle
PixelColor rectcolor = General.Colors.Highlight.WithAlpha(RECTANGLE_ALPHA);
renderer.RenderGeometry(cornerverts, null, true);
renderer.RenderLine(corners[0], corners[1], 4, rectcolor, true);
renderer.RenderLine(corners[1], corners[2], 4, rectcolor, true);
renderer.RenderLine(corners[2], corners[3], 4, rectcolor, true);
renderer.RenderLine(corners[3], corners[0], 4, rectcolor, true);
// Extension line
if(extensionline.GetLengthSq() > 0.0f)
renderer.RenderLine(extensionline.v1, extensionline.v2, 1, General.Colors.Indication.WithAlpha(EXTENSION_LINE_ALPHA), true);
// Grips
for(int i = 0; i < 4; i++)
{
renderer.RenderRectangleFilled(resizegrips[i], General.Colors.Background, true);
renderer.RenderRectangle(resizegrips[i], 2, General.Colors.Highlight, true);
renderer.RenderRectangleFilled(rotategrips[i], General.Colors.Background, true);
renderer.RenderRectangle(rotategrips[i], 2, General.Colors.Indication, true);
}
renderer.Finish();
}
renderer.Present();
}
// Mouse moves
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Update();
}
// Mouse leaves the display
public override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
// Reset cursor
General.Interface.SetCursor(Cursors.Default);
}
// When edit button is pressed
protected override void OnEdit()
{
base.OnEdit();
OnSelect();
}
// When edit button is released
protected override void OnEndEdit()
{
base.OnEndEdit();
OnEndSelect();
}
// When select button is pressed
protected override void OnSelect()
{
base.OnSelect();
// Used in many cases:
Vector2D center = offset + size * 0.5f;
Vector2D delta;
// Check what grip the mouse is over
switch(CheckMouseGrip())
{
// Drag main rectangle
case Grip.Main:
// Find the original position of the highlighted vertex
if(highlighted != null)
{
int index = 0;
foreach(Vertex v in selectedvertices)
{
if(v == highlighted) highlightedpos = vertexpos[index];
index++;
}
}
dragoffset = mousemappos - offset;
mode = ModifyMode.Dragging;
break;
// Resize
case Grip.SizeN:
// The resize vector is a unit vector in the direction of the resize.
// We multiply this with the sign of the current size, because the
// corners may be reversed when the selection is flipped.
resizevector = corners[1] - corners[2];
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
// The edgevector is a vector with length and direction of the edge perpendicular to the resizevector
edgevector = corners[1] - corners[0];
// Make the resize axis. This is a line with the length and direction
// of basesize used to calculate the resize percentage.
resizeaxis = new Line2D(corners[2], corners[2] + resizevector * basesize.y);
// Original axis filter
resizefilter = new Vector2D(0.0f, 1.0f);
// This is the corner that must stay in the same position
stickcorner = 2;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Resize
case Grip.SizeE:
// See description above
resizevector = corners[1] - corners[0];
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
edgevector = corners[1] - corners[2];
resizeaxis = new Line2D(corners[0], corners[0] + resizevector * basesize.x);
resizefilter = new Vector2D(1.0f, 0.0f);
stickcorner = 0;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Resize
case Grip.SizeS:
// See description above
resizevector = corners[2] - corners[1];
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
edgevector = corners[2] - corners[3];
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.y);
resizefilter = new Vector2D(0.0f, 1.0f);
stickcorner = 0;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Resize
case Grip.SizeW:
// See description above
resizevector = corners[0] - corners[1];
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
edgevector = corners[0] - corners[3];
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.x);
resizefilter = new Vector2D(1.0f, 0.0f);
stickcorner = 1;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Rotate
case Grip.RotateLB:
delta = corners[3] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Rotate
case Grip.RotateLT:
delta = corners[0] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Rotate
case Grip.RotateRB:
delta = corners[2] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Rotate
case Grip.RotateRT:
delta = corners[1] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Outside the selection?
default:
// Accept and be done with it
General.Map.AcceptMode();
break;
}
}
// When selected button is released
protected override void OnEndSelect()
{
base.OnEndSelect();
// Remove extension line
extensionline = new Line2D();
// No modifying mode
mode = ModifyMode.None;
// Redraw
General.Interface.RedrawDisplay();
}
// When a key is released
public override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
}
// When a key is pressed
public override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
}
#endregion #endregion
#region ================== Methods #region ================== Methods
// This clears the selection
[BeginAction("clearselection", BaseAction = true)]
public void ClearSelection()
{
// Accept changes
General.Map.Map.ClearAllSelected();
General.Map.AcceptMode();
}
// This highlights a new vertex // This highlights a new vertex
protected void Highlight(Vertex v) protected void Highlight(Vertex v)
{ {
@ -1031,5 +575,456 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
#endregion #endregion
#region ================== Events
// Mode engages
public override void OnEngage()
{
base.OnEngage();
// Convert geometry selection
General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true);
General.Map.Map.MarkSelectedThings(true, true);
General.Map.Map.MarkSelectedLinedefs(true, true);
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
foreach(Vertex v in verts) v.Marked = true;
selectedvertices = General.Map.Map.GetMarkedVertices(true);
selectedthings = General.Map.Map.GetMarkedThings(true);
unselectedvertices = General.Map.Map.GetMarkedVertices(false);
// Make sure everything is selected so that it turns up red
foreach(Vertex v in selectedvertices) v.Selected = true;
ICollection<Linedef> markedlines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in markedlines) l.Selected = true;
unselectedlines = General.Map.Map.LinedefsFromMarkedVertices(true, false, false);
// Array to keep original coordinates
vertexpos = new List<Vector2D>(selectedvertices.Count);
thingpos = new List<Vector2D>(selectedthings.Count);
// A selection must be made!
if((selectedvertices.Count > 0) || (selectedthings.Count > 0))
{
// Initialize offset and size
offset.x = float.MaxValue;
offset.y = float.MaxValue;
Vector2D right;
right.x = float.MinValue;
right.y = float.MinValue;
foreach(Vertex v in selectedvertices)
{
// Find left-top and right-bottom
if(v.Position.x < offset.x) offset.x = v.Position.x;
if(v.Position.y < offset.y) offset.y = v.Position.y;
if(v.Position.x > right.x) right.x = v.Position.x;
if(v.Position.y > right.y) right.y = v.Position.y;
// Keep original coordinates
vertexpos.Add(v.Position);
}
foreach(Thing t in selectedthings)
{
// Find left-top and right-bottom
if(t.Position.x < offset.x) offset.x = t.Position.x;
if(t.Position.y < offset.y) offset.y = t.Position.y;
if(t.Position.x > right.x) right.x = t.Position.x;
if(t.Position.y > right.y) right.y = t.Position.y;
// Keep original coordinates
thingpos.Add(t.Position);
}
// Calculate size
size = right - offset;
// If the width of a dimension is zero, add a little
if(Math.Abs(size.x) < 1.0f)
{
size.x += ZERO_SIZE_ADDITION;
offset.x -= ZERO_SIZE_ADDITION / 2;
}
if(Math.Abs(size.y) < 1.0f)
{
size.y += ZERO_SIZE_ADDITION;
offset.y -= ZERO_SIZE_ADDITION / 2;
}
basesize = size;
baseoffset = offset;
// Set presentation
if(selectedthings.Count > 0)
renderer.SetPresentation(Presentation.Things);
else
renderer.SetPresentation(Presentation.Standard);
// Update
UpdateRectangleComponents();
}
else
{
General.Interface.DisplayWarning("Please make a selection first!");
// Cancel now
General.Map.CancelMode();
}
}
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Reset geometry in original position
int index = 0;
foreach(Vertex v in selectedvertices)
v.Move(vertexpos[index++]);
index = 0;
foreach(Thing t in selectedthings)
t.Move(thingpos[index++]);
General.Map.Map.Update(true, true);
// Return to previous stable mode
General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// When accepted
public override void OnAccept()
{
base.OnAccept();
// Anything to do?
if((selectedthings.Count > 0) || (selectedvertices.Count > 0))
{
Cursor.Current = Cursors.AppStarting;
// Reset geometry in original position
int index = 0;
foreach(Vertex v in selectedvertices)
v.Move(vertexpos[index++]);
index = 0;
foreach(Thing t in selectedthings)
t.Move(thingpos[index++]);
// Make undo
General.Map.UndoRedo.CreateUndo("Edit selection", UndoGroup.None, 0);
// Move geometry to new position
UpdateGeometry();
General.Map.Map.Update(true, true);
// Stitch geometry
if(snaptonearest) General.Map.Map.StitchGeometry();
// Snap to map format accuracy
General.Map.Map.SnapAllToAccuracy();
// Update cached values
General.Map.Map.Update();
// Done
selectedvertices = new List<Vertex>();
selectedthings = new List<Thing>();
Cursor.Current = Cursors.Default;
General.Map.IsChanged = true;
}
if(!modealreadyswitching)
{
// Return to previous stable mode
General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// When not cancelled manually, we assume it is accepted
if(!cancelled)
{
modealreadyswitching = true;
this.OnAccept();
}
// Hide highlight info
General.Interface.HideInfo();
General.Interface.SetCursor(Cursors.Default);
}
// This redraws the display
public override void OnRedrawDisplay()
{
UpdateRectangleComponents();
// Render lines
if(renderer.StartPlotter(true))
{
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
renderer.PlotVerticesSet(General.Map.Map.Vertices);
if(highlighted != null) renderer.PlotVertex(highlighted, ColorCollection.HIGHLIGHT);
renderer.Finish();
}
// Render things
if(renderer.StartThings(true))
{
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
renderer.Finish();
}
// Render selection
if(renderer.StartOverlay(true))
{
// Rectangle
PixelColor rectcolor = General.Colors.Highlight.WithAlpha(RECTANGLE_ALPHA);
renderer.RenderGeometry(cornerverts, null, true);
renderer.RenderLine(corners[0], corners[1], 4, rectcolor, true);
renderer.RenderLine(corners[1], corners[2], 4, rectcolor, true);
renderer.RenderLine(corners[2], corners[3], 4, rectcolor, true);
renderer.RenderLine(corners[3], corners[0], 4, rectcolor, true);
// Extension line
if(extensionline.GetLengthSq() > 0.0f)
renderer.RenderLine(extensionline.v1, extensionline.v2, 1, General.Colors.Indication.WithAlpha(EXTENSION_LINE_ALPHA), true);
// Grips
for(int i = 0; i < 4; i++)
{
renderer.RenderRectangleFilled(resizegrips[i], General.Colors.Background, true);
renderer.RenderRectangle(resizegrips[i], 2, General.Colors.Highlight, true);
renderer.RenderRectangleFilled(rotategrips[i], General.Colors.Background, true);
renderer.RenderRectangle(rotategrips[i], 2, General.Colors.Indication, true);
}
renderer.Finish();
}
renderer.Present();
}
// Mouse moves
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Update();
}
// Mouse leaves the display
public override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
// Reset cursor
General.Interface.SetCursor(Cursors.Default);
}
// When edit button is pressed
protected override void OnEdit()
{
base.OnEdit();
OnSelect();
}
// When edit button is released
protected override void OnEndEdit()
{
base.OnEndEdit();
OnEndSelect();
}
// When select button is pressed
protected override void OnSelect()
{
base.OnSelect();
// Used in many cases:
Vector2D center = offset + size * 0.5f;
Vector2D delta;
// Check what grip the mouse is over
switch(CheckMouseGrip())
{
// Drag main rectangle
case Grip.Main:
// Find the original position of the highlighted vertex
if(highlighted != null)
{
int index = 0;
foreach(Vertex v in selectedvertices)
{
if(v == highlighted) highlightedpos = vertexpos[index];
index++;
}
}
dragoffset = mousemappos - offset;
mode = ModifyMode.Dragging;
break;
// Resize
case Grip.SizeN:
// The resize vector is a unit vector in the direction of the resize.
// We multiply this with the sign of the current size, because the
// corners may be reversed when the selection is flipped.
resizevector = corners[1] - corners[2];
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
// The edgevector is a vector with length and direction of the edge perpendicular to the resizevector
edgevector = corners[1] - corners[0];
// Make the resize axis. This is a line with the length and direction
// of basesize used to calculate the resize percentage.
resizeaxis = new Line2D(corners[2], corners[2] + resizevector * basesize.y);
// Original axis filter
resizefilter = new Vector2D(0.0f, 1.0f);
// This is the corner that must stay in the same position
stickcorner = 2;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Resize
case Grip.SizeE:
// See description above
resizevector = corners[1] - corners[0];
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
edgevector = corners[1] - corners[2];
resizeaxis = new Line2D(corners[0], corners[0] + resizevector * basesize.x);
resizefilter = new Vector2D(1.0f, 0.0f);
stickcorner = 0;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Resize
case Grip.SizeS:
// See description above
resizevector = corners[2] - corners[1];
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
edgevector = corners[2] - corners[3];
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.y);
resizefilter = new Vector2D(0.0f, 1.0f);
stickcorner = 0;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Resize
case Grip.SizeW:
// See description above
resizevector = corners[0] - corners[1];
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
edgevector = corners[0] - corners[3];
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.x);
resizefilter = new Vector2D(1.0f, 0.0f);
stickcorner = 1;
Highlight(null);
mode = ModifyMode.Resizing;
break;
// Rotate
case Grip.RotateLB:
delta = corners[3] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Rotate
case Grip.RotateLT:
delta = corners[0] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Rotate
case Grip.RotateRB:
delta = corners[2] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Rotate
case Grip.RotateRT:
delta = corners[1] - center;
rotategripangle = delta.GetAngle() - rotation;
Highlight(null);
mode = ModifyMode.Rotating;
break;
// Outside the selection?
default:
// Accept and be done with it
General.Map.AcceptMode();
break;
}
}
// When selected button is released
protected override void OnEndSelect()
{
base.OnEndSelect();
// Remove extension line
extensionline = new Line2D();
// No modifying mode
mode = ModifyMode.None;
// Redraw
General.Interface.RedrawDisplay();
}
// When a key is released
public override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
}
// When a key is pressed
public override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
}
#endregion
#region ================== Actions
// This clears the selection
[BeginAction("clearselection", BaseAction = true)]
public void ClearSelection()
{
// Accept changes
General.Map.Map.ClearAllSelected();
General.Map.AcceptMode();
}
#endregion
} }
} }

View file

@ -40,7 +40,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
SwitchAction = "findmode", SwitchAction = "findmode",
Volatile = true)] Volatile = true)]
public sealed class FindReplaceMode : ClassicMode public sealed class FindReplaceMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -48,41 +48,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables #region ================== Variables
// Mode to return to
private EditMode basemode;
#endregion #endregion
#region ================== Properties #region ================== Properties
internal EditMode BaseMode { get { return basemode; } }
#endregion #endregion
#region ================== Constructor / Disposer #region ================== Constructor / Disposer
// Constructor
public FindReplaceMode()
{
this.basemode = General.Map.Mode;
}
// Disposer
public override void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
// Done
base.Dispose();
}
}
#endregion #endregion
#region ================== Methods #region ================== Events
// Cancelled // Cancelled
public override void OnCancel() public override void OnCancel()
@ -91,7 +67,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel(); base.OnCancel();
// Return to base mode // Return to base mode
General.Map.ChangeMode(basemode.GetType().Name); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
} }
// Mode engages // Mode engages
@ -127,7 +103,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.IsChanged = true; General.Map.IsChanged = true;
// Return to base mode // Return to base mode
General.Map.ChangeMode(basemode); General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
} }
// Redrawing display // Redrawing display

View file

@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "LinesMode.png", // Image resource name for the button ButtonImage = "LinesMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 100)] // Position of the button (lower is more to the left) ButtonOrder = int.MinValue + 100)] // Position of the button (lower is more to the left)
public class LinedefsMode : ClassicMode public class LinedefsMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -70,109 +70,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Constructor / Disposer #region ================== Constructor / Disposer
// Constructor
public LinedefsMode()
{
}
// Disposer
public override void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
// Dispose base
base.Dispose();
}
}
#endregion #endregion
#region ================== Methods #region ================== Methods
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Return to this mode
General.Map.ChangeMode(new LinedefsMode());
}
// Mode engages
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
// Convert geometry selection to linedefs selection
General.Map.Map.ClearAllMarks();
General.Map.Map.MarkSelectedVertices(true, true);
ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in lines) l.Selected = true;
General.Map.Map.ClearSelectedSectors();
General.Map.Map.ClearSelectedVertices();
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// Going to EditSelectionMode?
if(General.Map.NewMode is EditSelectionMode)
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedLinedefs(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
}
// Hide highlight info
General.Interface.HideInfo();
}
// This redraws the display
public override void OnRedrawDisplay()
{
// Render lines
if(renderer.StartPlotter(true))
{
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.PlotAssociations(renderer, association[i]);
if((highlighted != null) && !highlighted.IsDisposed)
{
BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso);
renderer.PlotLinedef(highlighted, General.Colors.Highlight);
}
renderer.PlotVerticesSet(General.Map.Map.Vertices);
renderer.Finish();
}
// Render things
if(renderer.StartThings(true))
{
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
renderer.Finish();
}
// Render selection
if(renderer.StartOverlay(true))
{
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.RenderAssociations(renderer, association[i]);
if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso);
if(selecting) RenderMultiSelection();
renderer.Finish();
}
renderer.Present();
}
// This highlights a new item // This highlights a new item
protected void Highlight(Linedef l) protected void Highlight(Linedef l)
{ {
@ -267,6 +168,91 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Interface.HideInfo(); General.Interface.HideInfo();
} }
#endregion
#region ================== Events
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Return to this mode
General.Map.ChangeMode(new LinedefsMode());
}
// Mode engages
public override void OnEngage()
{
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
// Convert geometry selection to linedefs selection
General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true);
ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in lines) l.Selected = true;
General.Map.Map.ClearSelectedSectors();
General.Map.Map.ClearSelectedVertices();
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// Going to EditSelectionMode?
if(General.Map.NewMode is EditSelectionMode)
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedLinedefs(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
}
// Hide highlight info
General.Interface.HideInfo();
}
// This redraws the display
public override void OnRedrawDisplay()
{
// Render lines
if(renderer.StartPlotter(true))
{
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.PlotAssociations(renderer, association[i]);
if((highlighted != null) && !highlighted.IsDisposed)
{
BuilderPlug.Me.PlotReverseAssociations(renderer, highlightasso);
renderer.PlotLinedef(highlighted, General.Colors.Highlight);
}
renderer.PlotVerticesSet(General.Map.Map.Vertices);
renderer.Finish();
}
// Render things
if(renderer.StartThings(true))
{
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
renderer.Finish();
}
// Render selection
if(renderer.StartOverlay(true))
{
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.Me.RenderAssociations(renderer, association[i]);
if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.Me.RenderReverseAssociations(renderer, highlightasso);
if(selecting) RenderMultiSelection();
renderer.Finish();
}
renderer.Present();
}
// Selection // Selection
protected override void OnSelect() protected override void OnSelect()
{ {
@ -478,13 +464,27 @@ namespace CodeImp.DoomBuilder.BuilderModes
// When copying // When copying
public override bool OnCopyBegin() public override bool OnCopyBegin()
{ {
return true; // No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedSectors(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
return base.OnCopyBegin();
} }
// When pasting // When pasting
public override bool OnPasteBegin() public override bool OnPasteBegin()
{ {
return true; // No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedSectors(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
return base.OnPasteBegin();
} }
#endregion #endregion

View file

@ -43,7 +43,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "NewSector2.png", // Image resource name for the button ButtonImage = "NewSector2.png", // Image resource name for the button
ButtonOrder = int.MinValue + 202)] // Position of the button (lower is more to the left) ButtonOrder = int.MinValue + 202)] // Position of the button (lower is more to the left)
public class MakeSectorMode : ClassicMode public class MakeSectorMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -100,77 +100,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Methods #region ================== Methods
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Return to base mode
General.Map.ChangeMode(new SectorsMode());
}
// Mode engages
public override void OnEngage()
{
base.OnEngage();
// Make customized presentation
CustomPresentation p = new CustomPresentation();
p.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask));
p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
p.AddLayer(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, Presentation.THINGS_BACK_ALPHA, false));
p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
renderer.SetPresentation(p);
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// Check which mode we are switching to
if(General.Map.NewMode is VerticesMode)
{
// Convert selection to vertices
// Clear selected sectors
General.Map.Map.ClearSelectedSectors();
}
else if(General.Map.NewMode is LinedefsMode)
{
// Convert selection to linedefs
// Clear selected sectors
General.Map.Map.ClearSelectedSectors();
}
// Hide highlight info
General.Interface.HideInfo();
// Stop processing
General.Interface.SetProcessorState(false);
}
// This redraws the display
public override void OnRedrawDisplay()
{
// Render lines and vertices
DrawGeometry();
// Render things
if(renderer.StartThings(true))
{
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
renderer.Finish();
}
// Render overlay
DrawOverlay();
renderer.Present();
}
// This draws the geometry // This draws the geometry
private void DrawGeometry() private void DrawGeometry()
{ {
@ -272,6 +201,81 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnEdit(); base.OnEdit();
} }
#endregion
#region ================== Events
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Return to base mode
General.Map.ChangeMode(new SectorsMode());
}
// Mode engages
public override void OnEngage()
{
base.OnEngage();
// Make customized presentation
CustomPresentation p = new CustomPresentation();
p.AddLayer(new PresentLayer(RendererLayer.Background, BlendingMode.Mask));
p.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
p.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Alpha, 1f, true));
p.AddLayer(new PresentLayer(RendererLayer.Things, BlendingMode.Alpha, Presentation.THINGS_BACK_ALPHA, false));
p.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
renderer.SetPresentation(p);
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// Check which mode we are switching to
if(General.Map.NewMode is VerticesMode)
{
// Convert selection to vertices
// Clear selected sectors
General.Map.Map.ClearSelectedSectors();
}
else if(General.Map.NewMode is LinedefsMode)
{
// Convert selection to linedefs
// Clear selected sectors
General.Map.Map.ClearSelectedSectors();
}
// Hide highlight info
General.Interface.HideInfo();
// Stop processing
General.Interface.SetProcessorState(false);
}
// This redraws the display
public override void OnRedrawDisplay()
{
// Render lines and vertices
DrawGeometry();
// Render things
if(renderer.StartThings(true))
{
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
renderer.Finish();
}
// Render overlay
DrawOverlay();
renderer.Present();
}
// Done selecting // Done selecting
protected override void OnEndSelect() protected override void OnEndSelect()
{ {

View file

@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "SectorsMode.png", // Image resource name for the button ButtonImage = "SectorsMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 200)] // Position of the button (lower is more to the left) ButtonOrder = int.MinValue + 200)] // Position of the button (lower is more to the left)
public class SectorsMode : ClassicMode public class SectorsMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -101,31 +101,105 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Methods #region ================== Methods
// This clears the selection // Support function for joining and merging sectors
[BeginAction("clearselection", BaseAction = true)] private void JoinMergeSectors(bool removelines)
public void ClearSelection()
{ {
// Clear selection // Remove lines in betwen joining sectors?
General.Map.Map.ClearAllSelected(); if(removelines)
{
// Go for all selected linedefs
ICollection<Linedef> selectedlines = General.Map.Map.GetSelectedLinedefs(true);
foreach(Linedef ld in selectedlines)
{
// Front and back side?
if((ld.Front != null) && (ld.Back != null))
{
// Both a selected sector, but not the same?
if(ld.Front.Sector.Selected && ld.Back.Sector.Selected &&
(ld.Front.Sector != ld.Back.Sector))
{
// Remove this line
ld.Dispose();
}
}
}
}
// Redraw // Join all selected sectors with the first
for(int i = 1; i < orderedselection.Count; i++)
orderedselection[i].Join(orderedselection[0]);
}
// This highlights a new item
protected void Highlight(Sector s)
{
bool completeredraw = false;
// Often we can get away by simply undrawing the previous
// highlight and drawing the new highlight. But if associations
// are or were drawn we need to redraw the entire display.
// Previous association highlights something?
if((highlighted != null) && (highlighted.Tag > 0)) completeredraw = true;
// Set highlight association
if(s != null)
highlightasso.Set(s.Tag, UniversalType.SectorTag);
else
highlightasso.Set(0, 0);
// New association highlights something?
if((s != null) && (s.Tag > 0)) completeredraw = true;
// If we're changing associations, then we
// need to redraw the entire display
if(completeredraw)
{
// Set new highlight and redraw completely
highlighted = s;
General.Interface.RedrawDisplay(); General.Interface.RedrawDisplay();
} }
else
// When undo is used
[EndAction("undo", BaseAction = true)]
public void Undo()
{ {
// Clear ordered selection // Update display
orderedselection.Clear(); if(renderer.StartPlotter(false))
{
// Undraw previous highlight
if((highlighted != null) && !highlighted.IsDisposed)
renderer.PlotSector(highlighted);
/*
// Undraw highlighted things
if(highlighted != null)
foreach(Thing t in highlighted.Things)
renderer.RenderThing(t, renderer.DetermineThingColor(t));
*/
// Set new highlight
highlighted = s;
// Render highlighted item
if((highlighted != null) && !highlighted.IsDisposed)
renderer.PlotSector(highlighted, General.Colors.Highlight);
/*
// Render highlighted things
if(highlighted != null)
foreach(Thing t in highlighted.Things)
renderer.RenderThing(t, General.Colors.Highlight);
*/
// Done
renderer.Finish();
renderer.Present();
}
} }
// When redo is used // Show highlight info
[EndAction("redo", BaseAction = true)] if((highlighted != null) && !highlighted.IsDisposed)
public void Redo() General.Interface.ShowSectorInfo(highlighted);
{ else
// Clear ordered selection General.Interface.HideInfo();
orderedselection.Clear();
} }
// This selectes or deselects a sector // This selectes or deselects a sector
@ -162,6 +236,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
#endregion
#region ================== Events
// Cancel mode // Cancel mode
public override void OnCancel() public override void OnCancel()
{ {
@ -178,7 +256,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.SetPresentation(Presentation.Standard); renderer.SetPresentation(Presentation.Standard);
// Convert geometry selection to sectors only // Convert geometry selection to sectors only
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true); General.Map.Map.MarkSelectedVertices(true, true);
ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false); ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in lines) l.Selected = true; foreach(Linedef l in lines) l.Selected = true;
@ -257,78 +335,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Present(); renderer.Present();
} }
// This highlights a new item
protected void Highlight(Sector s)
{
bool completeredraw = false;
// Often we can get away by simply undrawing the previous
// highlight and drawing the new highlight. But if associations
// are or were drawn we need to redraw the entire display.
// Previous association highlights something?
if((highlighted != null) && (highlighted.Tag > 0)) completeredraw = true;
// Set highlight association
if(s != null)
highlightasso.Set(s.Tag, UniversalType.SectorTag);
else
highlightasso.Set(0, 0);
// New association highlights something?
if((s != null) && (s.Tag > 0)) completeredraw = true;
// If we're changing associations, then we
// need to redraw the entire display
if(completeredraw)
{
// Set new highlight and redraw completely
highlighted = s;
General.Interface.RedrawDisplay();
}
else
{
// Update display
if(renderer.StartPlotter(false))
{
// Undraw previous highlight
if((highlighted != null) && !highlighted.IsDisposed)
renderer.PlotSector(highlighted);
/*
// Undraw highlighted things
if(highlighted != null)
foreach(Thing t in highlighted.Things)
renderer.RenderThing(t, renderer.DetermineThingColor(t));
*/
// Set new highlight
highlighted = s;
// Render highlighted item
if((highlighted != null) && !highlighted.IsDisposed)
renderer.PlotSector(highlighted, General.Colors.Highlight);
/*
// Render highlighted things
if(highlighted != null)
foreach(Thing t in highlighted.Things)
renderer.RenderThing(t, General.Colors.Highlight);
*/
// Done
renderer.Finish();
renderer.Present();
}
}
// Show highlight info
if((highlighted != null) && !highlighted.IsDisposed)
General.Interface.ShowSectorInfo(highlighted);
else
General.Interface.HideInfo();
}
// Selection // Selection
protected override void OnSelect() protected override void OnSelect()
{ {
@ -589,6 +595,50 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
// When copying
public override bool OnCopyBegin()
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedSectors(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
SelectSector(highlighted, true);
}
return base.OnCopyBegin();
}
// When pasting
public override bool OnPasteBegin()
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedSectors(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
SelectSector(highlighted, true);
}
return base.OnPasteBegin();
}
// When undo is used
public override bool OnUndoBegin()
{
// Clear ordered selection
orderedselection.Clear();
return base.OnUndoBegin();
}
// When redo is used
public override bool OnRedoBegin()
{
// Clear ordered selection
orderedselection.Clear();
return base.OnRedoBegin();
}
#endregion #endregion
#region ================== Actions #region ================== Actions
@ -721,33 +771,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
// Support function for joining and merging sectors // This clears the selection
private void JoinMergeSectors(bool removelines) [BeginAction("clearselection", BaseAction = true)]
public void ClearSelection()
{ {
// Remove lines in betwen joining sectors? // Clear selection
if(removelines) General.Map.Map.ClearAllSelected();
{
// Go for all selected linedefs
ICollection<Linedef> selectedlines = General.Map.Map.GetSelectedLinedefs(true);
foreach(Linedef ld in selectedlines)
{
// Front and back side?
if((ld.Front != null) && (ld.Back != null))
{
// Both a selected sector, but not the same?
if(ld.Front.Sector.Selected && ld.Back.Sector.Selected &&
(ld.Front.Sector != ld.Back.Sector))
{
// Remove this line
ld.Dispose();
}
}
}
}
// Join all selected sectors with the first // Redraw
for(int i = 1; i < orderedselection.Count; i++) General.Interface.RedrawDisplay();
orderedselection[i].Join(orderedselection[0]);
} }
#endregion #endregion

View file

@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "ThingsMode.png", // Image resource name for the button ButtonImage = "ThingsMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 300)] // Position of the button (lower is more to the left) ButtonOrder = int.MinValue + 300)] // Position of the button (lower is more to the left)
public class ThingsMode : ClassicMode public class ThingsMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -70,24 +70,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Constructor / Disposer #region ================== Constructor / Disposer
// Constructor
public ThingsMode()
{
}
// Disposer
public override void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
// Dispose base
base.Dispose();
}
}
#endregion #endregion
#region ================== Methods #region ================== Methods
@ -108,7 +90,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.SetPresentation(Presentation.Things); renderer.SetPresentation(Presentation.Things);
// Convert geometry selection to linedefs selection // Convert geometry selection to linedefs selection
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true); General.Map.Map.MarkSelectedVertices(true, true);
ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false); ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in lines) l.Selected = true; foreach(Linedef l in lines) l.Selected = true;
@ -457,6 +439,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
// When copying
public override bool OnCopyBegin()
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedThings(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
return base.OnCopyBegin();
}
// When pasting
public override bool OnPasteBegin()
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedThings(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
return base.OnPasteBegin();
}
#endregion #endregion
#region ================== Actions #region ================== Actions

View file

@ -42,7 +42,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "VerticesMode.png", // Image resource name for the button ButtonImage = "VerticesMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 0)] // Position of the button (lower is more to the left) ButtonOrder = int.MinValue + 0)] // Position of the button (lower is more to the left)
public class VerticesMode : ClassicMode public class VerticesMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Constants
@ -67,24 +67,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Constructor / Disposer #region ================== Constructor / Disposer
// Constructor
public VerticesMode()
{
}
// Disposer
public override void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
// Dispose base
base.Dispose();
}
}
#endregion #endregion
#region ================== Methods #region ================== Methods
@ -107,7 +89,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.SetPresentation(Presentation.Standard); renderer.SetPresentation(Presentation.Standard);
// Convert geometry selection to vertices only // Convert geometry selection to vertices only
General.Map.Map.ClearAllMarks(); General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedLinedefs(true, true); General.Map.Map.MarkSelectedLinedefs(true, true);
General.Map.Map.MarkSelectedSectors(true, true); General.Map.Map.MarkSelectedSectors(true, true);
verts = General.Map.Map.GetVerticesFromLinesMarks(true); verts = General.Map.Map.GetVerticesFromLinesMarks(true);
@ -390,6 +372,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
// When copying
public override bool OnCopyBegin()
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedVertices(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
return base.OnCopyBegin();
}
// When pasting
public override bool OnPasteBegin()
{
// No selection made? But we have a highlight!
if((General.Map.Map.GetSelectedVertices(true).Count == 0) && (highlighted != null))
{
// Make the highlight the selection
highlighted.Selected = true;
}
return base.OnPasteBegin();
}
#endregion #endregion
#region ================== Actions #region ================== Actions

View file

@ -144,6 +144,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
// This renders the associated things with the indication color // This renders the associated things with the indication color
public void RenderAssociations(IRenderer2D renderer, Association asso) public void RenderAssociations(IRenderer2D renderer, Association asso)
{ {
@ -160,6 +161,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
// This renders the associated sectors/linedefs with the indication color // This renders the associated sectors/linedefs with the indication color
public void PlotReverseAssociations(IRenderer2D renderer, Association asso) public void PlotReverseAssociations(IRenderer2D renderer, Association asso)
{ {
@ -182,6 +184,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
} }
// This renders the associated things with the indication color // This renders the associated things with the indication color
public void RenderReverseAssociations(IRenderer2D renderer, Association asso) public void RenderReverseAssociations(IRenderer2D renderer, Association asso)
{ {

View file

@ -117,16 +117,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This shows the menu for the current editing mode // This shows the menu for the current editing mode
public void ShowEditingModeMenu(EditMode mode) public void ShowEditingModeMenu(EditMode mode)
{ {
Type sourcemode = typeof(object);
if(mode != null) sourcemode = mode.GetType();
// When these modes are active, then test against the base mode they will return to // When these modes are active, then test against the base mode they will return to
if(mode is DragGeometryMode) mode = (mode as DragGeometryMode).BaseMode; if((mode is DragGeometryMode) || (mode is DragThingsMode) ||
if(mode is DragThingsMode) mode = (mode as DragThingsMode).BaseMode; (mode is DrawGeometryMode) || (mode is CurveLinedefsMode))
if(mode is DrawGeometryMode) mode = (mode as DrawGeometryMode).BaseMode; sourcemode = General.Map.PreviousStableMode;
if(mode is CurveLinedefsMode) mode = (mode as CurveLinedefsMode).BaseMode;
// Final decision // Final decision
if(mode is LinedefsMode) HideAllMenusExcept(linedefsmenu); if(sourcemode == typeof(LinedefsMode)) HideAllMenusExcept(linedefsmenu);
else if(mode is SectorsMode) HideAllMenusExcept(sectorsmenu); else if(sourcemode == typeof(SectorsMode)) HideAllMenusExcept(sectorsmenu);
else if(mode is ThingsMode) HideAllMenusExcept(thingsmenu); else if(sourcemode == typeof(ThingsMode)) HideAllMenusExcept(thingsmenu);
else HideAllMenus(); else HideAllMenus();
} }

View file

@ -43,6 +43,7 @@ namespace CodeImp.DoomBuilder.Config
private Configuration cfg; private Configuration cfg;
// General settings // General settings
private string configname;
private string enginename; private string enginename;
private float defaulttexturescale; private float defaulttexturescale;
private float defaultflatscale; private float defaultflatscale;
@ -102,6 +103,7 @@ namespace CodeImp.DoomBuilder.Config
#region ================== Properties #region ================== Properties
// General settings // General settings
public string Name { get { return configname; } }
public string EngineName { get { return enginename; } } public string EngineName { get { return enginename; } }
public float DefaultTextureScale { get { return defaulttexturescale; } } public float DefaultTextureScale { get { return defaulttexturescale; } }
public float DefaultFlatScale { get { return defaultflatscale; } } public float DefaultFlatScale { get { return defaultflatscale; } }
@ -184,6 +186,7 @@ namespace CodeImp.DoomBuilder.Config
this.skills = new List<SkillInfo>(); this.skills = new List<SkillInfo>();
// Read general settings // Read general settings
configname = cfg.ReadSetting("game", "<unnamed game>");
enginename = cfg.ReadSetting("engine", ""); enginename = cfg.ReadSetting("engine", "");
defaulttexturescale = cfg.ReadSetting("defaulttexturescale", 1f); defaulttexturescale = cfg.ReadSetting("defaulttexturescale", 1f);
defaultflatscale = cfg.ReadSetting("defaultflatscale", 1f); defaultflatscale = cfg.ReadSetting("defaultflatscale", 1f);

View file

@ -96,22 +96,25 @@ namespace CodeImp.DoomBuilder.Editing
// that need to be copied. // that need to be copied.
if(General.Map.Mode.OnCopyBegin()) if(General.Map.Mode.OnCopyBegin())
{ {
MapSet copyset = new MapSet(); // Get all marked elements
ICollection<Vertex> verts = General.Map.Map.GetMarkedVertices(true);
// Copy all data over ICollection<Sidedef> sides = General.Map.Map.GetMarkedSidedefs(true);
copyset = General.Map.Map.Clone(); ICollection<Sector> sectors = General.Map.Map.GetMarkedSectors(true);
ICollection<Linedef> lines = General.Map.Map.GetMarkedLinedefs(true);
ICollection<Thing> things = General.Map.Map.GetMarkedThings(true);
// Write data to stream // Write data to stream
MemoryStream memstream = new MemoryStream(); MemoryStream memstream = new MemoryStream();
UniversalStreamWriter writer = new UniversalStreamWriter(); UniversalStreamWriter writer = new UniversalStreamWriter();
writer.RememberCustomTypes = false; writer.RememberCustomTypes = false;
writer.Write(copyset, memstream, null); writer.Write(verts, lines, sides, sectors, things, memstream, null);
// Set on clipboard // Set on clipboard
Clipboard.SetData(CLIPBOARD_DATA_FORMAT, memstream); Clipboard.SetData(CLIPBOARD_DATA_FORMAT, memstream);
// Done // Done
memstream.Dispose(); memstream.Dispose();
General.Map.Mode.OnCopyEnd();
return true; return true;
} }
else else
@ -123,21 +126,30 @@ namespace CodeImp.DoomBuilder.Editing
// This performs the paste. Returns false when paste was cancelled. // This performs the paste. Returns false when paste was cancelled.
private bool DoPasteSelection() private bool DoPasteSelection()
{
// Anything to paste?
if(Clipboard.ContainsData(CLIPBOARD_DATA_FORMAT))
{ {
// Ask the editing mode to prepare selection for pasting. // Ask the editing mode to prepare selection for pasting.
if(General.Map.Mode.OnPasteBegin()) if(General.Map.Mode.OnPasteBegin())
{ {
// TODO: Do the paste // Read from clipboard
if(Clipboard.ContainsData(CLIPBOARD_DATA_FORMAT))
{
Stream memstream = (Stream)Clipboard.GetData(CLIPBOARD_DATA_FORMAT); Stream memstream = (Stream)Clipboard.GetData(CLIPBOARD_DATA_FORMAT);
memstream.Seek(0, SeekOrigin.Begin); memstream.Seek(0, SeekOrigin.Begin);
StreamReader reader = new StreamReader(memstream, Encoding.ASCII);
//File.WriteAllText("C:\\Test.txt", reader.ReadToEnd());
memstream.Dispose();
}
// Mark all current geometry
General.Map.Map.ClearAllMarks(true);
// Read data stream
UniversalStreamReader reader = new UniversalStreamReader();
reader.Read(General.Map.Map, memstream);
// The new geometry is not marked, so invert the marks to get it marked
General.Map.Map.InvertAllMarks();
// Done
memstream.Dispose();
General.Map.Mode.OnPasteEnd();
return true; return true;
} }
else else
@ -146,6 +158,12 @@ namespace CodeImp.DoomBuilder.Editing
return false; return false;
} }
} }
else
{
General.MessageBeep(MessageBeepType.Warning);
return false;
}
}
#endregion #endregion

View file

@ -169,8 +169,19 @@ namespace CodeImp.DoomBuilder.Editing
// that need to be copied. // that need to be copied.
public virtual bool OnCopyBegin() { return false; } public virtual bool OnCopyBegin() { return false; }
// Called when the marked geometry has been copied.
public virtual void OnCopyEnd() { }
// Called before pasting. Return false when paste should be cancelled. // Called before pasting. Return false when paste should be cancelled.
public virtual bool OnPasteBegin() { return false; } public virtual bool OnPasteBegin() { return true; }
// Called after new geometry has been pasted in. The new geometry is marked.
public virtual void OnPasteEnd() { }
// Called when undo/redo is used
// Return false to cancel undo action
public virtual bool OnUndoBegin() { return true; }
public virtual bool OnRedoBegin() { return true; }
// Interface events // Interface events
public virtual void OnMouseClick(MouseEventArgs e) { } public virtual void OnMouseClick(MouseEventArgs e) { }

View file

@ -218,6 +218,9 @@ namespace CodeImp.DoomBuilder.Editing
Cursor oldcursor = Cursor.Current; Cursor oldcursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor; Cursor.Current = Cursors.WaitCursor;
// Call UndoBegin event
if(General.Map.Mode.OnUndoBegin())
{
// Cancel volatile mode, if any // Cancel volatile mode, if any
// This returns false when mode was not volatile // This returns false when mode was not volatile
if(!General.CancelVolatileMode()) if(!General.CancelVolatileMode())
@ -242,7 +245,7 @@ namespace CodeImp.DoomBuilder.Editing
lastgroup = UndoGroup.None; lastgroup = UndoGroup.None;
// Remove selection // Remove selection
u.map.ClearAllMarks(); u.map.ClearAllMarks(false);
u.map.ClearAllSelected(); u.map.ClearAllSelected();
// Change map set // Change map set
@ -253,6 +256,7 @@ namespace CodeImp.DoomBuilder.Editing
General.MainWindow.UpdateInterface(); General.MainWindow.UpdateInterface();
} }
} }
}
Cursor.Current = oldcursor; Cursor.Current = oldcursor;
} }
@ -265,6 +269,9 @@ namespace CodeImp.DoomBuilder.Editing
Cursor oldcursor = Cursor.Current; Cursor oldcursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor; Cursor.Current = Cursors.WaitCursor;
// Call RedoBegin event
if(General.Map.Mode.OnRedoBegin())
{
// Cancel volatile mode, if any // Cancel volatile mode, if any
General.CancelVolatileMode(); General.CancelVolatileMode();
@ -288,7 +295,7 @@ namespace CodeImp.DoomBuilder.Editing
lastgroup = UndoGroup.None; lastgroup = UndoGroup.None;
// Remove selection // Remove selection
r.map.ClearAllMarks(); r.map.ClearAllMarks(false);
r.map.ClearAllSelected(); r.map.ClearAllSelected();
// Change map set // Change map set
@ -298,6 +305,7 @@ namespace CodeImp.DoomBuilder.Editing
General.MainWindow.RedrawDisplay(); General.MainWindow.RedrawDisplay();
General.MainWindow.UpdateInterface(); General.MainWindow.UpdateInterface();
} }
}
Cursor.Current = oldcursor; Cursor.Current = oldcursor;
} }

View file

@ -76,6 +76,8 @@ namespace CodeImp.DoomBuilder
private DataManager data; private DataManager data;
private EditMode mode; private EditMode mode;
private EditMode newmode; private EditMode newmode;
private Type prevmode;
private Type prevstablemode;
private D3DDevice graphics; private D3DDevice graphics;
private Renderer2D renderer2d; private Renderer2D renderer2d;
private Renderer3D renderer3d; private Renderer3D renderer3d;
@ -101,6 +103,8 @@ namespace CodeImp.DoomBuilder
public MapSet Map { get { return map; } } public MapSet Map { get { return map; } }
public EditMode Mode { get { return mode; } } public EditMode Mode { get { return mode; } }
public EditMode NewMode { get { return newmode; } } public EditMode NewMode { get { return newmode; } }
public Type PreviousMode { get { return prevmode; } }
public Type PreviousStableMode { get { return prevstablemode; } }
public DataManager Data { get { return data; } } public DataManager Data { get { return data; } }
public bool IsChanged { get { return changed; } set { changed |= value; } } public bool IsChanged { get { return changed; } set { changed |= value; } }
public bool IsDisposed { get { return isdisposed; } } public bool IsDisposed { get { return isdisposed; } }
@ -862,7 +866,6 @@ namespace CodeImp.DoomBuilder
public void ChangeMode(EditMode nextmode) public void ChangeMode(EditMode nextmode)
{ {
EditMode oldmode = mode; EditMode oldmode = mode;
newmode = nextmode;
cancelmodechange = false; cancelmodechange = false;
// Log info // Log info
@ -871,6 +874,19 @@ namespace CodeImp.DoomBuilder
else else
General.WriteLogLine("Stopping edit mode..."); General.WriteLogLine("Stopping edit mode...");
// Remember previous mode
newmode = nextmode;
if(mode != null)
{
prevmode = mode.GetType();
if(!mode.Attributes.Volatile) prevstablemode = prevmode;
}
else
{
prevmode = null;
prevstablemode = null;
}
// Let the plugins know beforehand // Let the plugins know beforehand
General.Plugins.ModeChanges(oldmode, newmode); General.Plugins.ModeChanges(oldmode, newmode);

View file

@ -107,6 +107,17 @@ namespace CodeImp.DoomBuilder.IO
// This writes the structures to a stream // This writes the structures to a stream
// writenamespace may be null to omit writing the namespace to the stream // writenamespace may be null to omit writing the namespace to the stream
public void Write(MapSet map, Stream stream, string writenamespace) public void Write(MapSet map, Stream stream, string writenamespace)
{
Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, stream, writenamespace);
}
// This writes the structures to a stream
// NOTE: writenamespace may be null to omit writing the namespace to the stream.
// NOTE: The given structures must be complete, with the exception of the sidedefs.
// If there are missing sidedefs, their reference will be removed from the linedefs.
public void Write(ICollection<Vertex> vertices, ICollection<Linedef> linedefs,
ICollection<Sidedef> sidedefs, ICollection<Sector> sectors,
ICollection<Thing> things, Stream stream, string writenamespace)
{ {
UniversalParser textmap = new UniversalParser(); UniversalParser textmap = new UniversalParser();
@ -118,20 +129,20 @@ namespace CodeImp.DoomBuilder.IO
Dictionary<Sector, int> sectorids = new Dictionary<Sector, int>(); Dictionary<Sector, int> sectorids = new Dictionary<Sector, int>();
// Index the elements in the data structures // Index the elements in the data structures
foreach(Vertex v in map.Vertices) vertexids.Add(v, vertexids.Count); foreach(Vertex v in vertices) vertexids.Add(v, vertexids.Count);
foreach(Sidedef sd in map.Sidedefs) sidedefids.Add(sd, sidedefids.Count); foreach(Sidedef sd in sidedefs) sidedefids.Add(sd, sidedefids.Count);
foreach(Sector s in map.Sectors) sectorids.Add(s, sectorids.Count); foreach(Sector s in sectors) sectorids.Add(s, sectorids.Count);
// If we write the custom field types again, then forget // If we write the custom field types again, then forget
// all previous field types (this gets rid of unused field types) // all previous field types (this gets rid of unused field types)
if(remembercustomtypes) General.Map.Options.ForgetUniversalFieldTypes(); if(remembercustomtypes) General.Map.Options.ForgetUniversalFieldTypes();
// Write the data structures to textmap // Write the data structures to textmap
WriteVertices(map.Vertices, textmap); WriteVertices(vertices, textmap);
WriteLinedefs(map.Linedefs, textmap, sidedefids, vertexids); WriteLinedefs(linedefs, textmap, sidedefids, vertexids);
WriteSidedefs(map.Sidedefs, textmap, sectorids); WriteSidedefs(sidedefs, textmap, sectorids);
WriteSectors(map.Sectors, textmap); WriteSectors(sectors, textmap);
WriteThings(map.Things, textmap); WriteThings(things, textmap);
// Get the textmap as string // Get the textmap as string
string textmapstr = textmap.OutputConfiguration(); string textmapstr = textmap.OutputConfiguration();
@ -172,8 +183,19 @@ namespace CodeImp.DoomBuilder.IO
if(l.Tag != 0) coll.Add("id", l.Tag); if(l.Tag != 0) coll.Add("id", l.Tag);
coll.Add("v1", vertexids[l.Start]); coll.Add("v1", vertexids[l.Start]);
coll.Add("v2", vertexids[l.End]); coll.Add("v2", vertexids[l.End]);
if(l.Front != null) coll.Add("sidefront", sidedefids[l.Front]); else coll.Add("sidefront", -1);
if(l.Back != null) coll.Add("sideback", sidedefids[l.Back]); else coll.Add("sideback", -1); // Sidedef references
if((l.Front != null) && sidedefids.ContainsKey(l.Front))
coll.Add("sidefront", sidedefids[l.Front]);
else
coll.Add("sidefront", -1);
if((l.Back != null) && sidedefids.ContainsKey(l.Back))
coll.Add("sideback", sidedefids[l.Back]);
else
coll.Add("sideback", -1);
// Special
if(l.Action != 0) coll.Add("special", l.Action); if(l.Action != 0) coll.Add("special", l.Action);
if(l.Args[0] != 0) coll.Add("arg0", l.Args[0]); if(l.Args[0] != 0) coll.Add("arg0", l.Args[0]);
if(l.Args[1] != 0) coll.Add("arg1", l.Args[1]); if(l.Args[1] != 0) coll.Add("arg1", l.Args[1]);
@ -199,6 +221,8 @@ namespace CodeImp.DoomBuilder.IO
// Go for all sidedefs // Go for all sidedefs
foreach(Sidedef s in sidedefs) foreach(Sidedef s in sidedefs)
{ {
int sectorid = (s.Sector != null) ? sectorids[s.Sector] : -1;
// Make collection // Make collection
UniversalCollection coll = new UniversalCollection(); UniversalCollection coll = new UniversalCollection();
if(s.OffsetX != 0) coll.Add("offsetx", s.OffsetX); if(s.OffsetX != 0) coll.Add("offsetx", s.OffsetX);

View file

@ -441,18 +441,51 @@ namespace CodeImp.DoomBuilder.Map
return list; return list;
} }
// This selects geometry based on the marking
public void SelectMarkedGeometry(bool mark, bool select)
{
SelectMarkedVertices(mark, select);
SelectMarkedLinedefs(mark, select);
SelectMarkedSectors(mark, select);
SelectMarkedThings(mark, select);
}
// This selects geometry based on the marking
public void SelectMarkedVertices(bool mark, bool select)
{
foreach(Vertex v in vertices) if(v.Marked == mark) v.Selected = select;
}
// This selects geometry based on the marking
public void SelectMarkedLinedefs(bool mark, bool select)
{
foreach(Linedef l in linedefs) if(l.Marked == mark) l.Selected = select;
}
// This selects geometry based on the marking
public void SelectMarkedSectors(bool mark, bool select)
{
foreach(Sector s in sectors) if(s.Marked == mark) s.Selected = select;
}
// This selects geometry based on the marking
public void SelectMarkedThings(bool mark, bool select)
{
foreach(Thing t in things) if(t.Marked == mark) t.Selected = select;
}
#endregion #endregion
#region ================== Marking #region ================== Marking
// This clears all marks // This clears all marks
public void ClearAllMarks() public void ClearAllMarks(bool mark)
{ {
ClearMarkedVertices(false); ClearMarkedVertices(mark);
ClearMarkedThings(false); ClearMarkedThings(mark);
ClearMarkedLinedefs(false); ClearMarkedLinedefs(mark);
ClearMarkedSectors(false); ClearMarkedSectors(mark);
ClearMarkedSidedefs(false); ClearMarkedSidedefs(mark);
} }
// This clears marked vertices // This clears marked vertices
@ -485,6 +518,46 @@ namespace CodeImp.DoomBuilder.Map
foreach(Sector s in sectors) s.Marked = mark; foreach(Sector s in sectors) s.Marked = mark;
} }
// This inverts all marks
public void InvertAllMarks()
{
InvertMarkedVertices();
InvertMarkedThings();
InvertMarkedLinedefs();
InvertMarkedSectors();
InvertMarkedSidedefs();
}
// This inverts marked vertices
public void InvertMarkedVertices()
{
foreach(Vertex v in vertices) v.Marked = !v.Marked;
}
// This inverts marked things
public void InvertMarkedThings()
{
foreach(Thing t in things) t.Marked = !t.Marked;
}
// This inverts marked linedefs
public void InvertMarkedLinedefs()
{
foreach(Linedef l in linedefs) l.Marked = !l.Marked;
}
// This inverts marked sidedefs
public void InvertMarkedSidedefs()
{
foreach(Sidedef s in sidedefs) s.Marked = !s.Marked;
}
// This inverts marked sectors
public void InvertMarkedSectors()
{
foreach(Sector s in sectors) s.Marked = !s.Marked;
}
// Returns a collection of vertices that match a marked state // Returns a collection of vertices that match a marked state
public List<Vertex> GetMarkedVertices(bool mark) public List<Vertex> GetMarkedVertices(bool mark)
{ {
@ -509,6 +582,14 @@ namespace CodeImp.DoomBuilder.Map
return list; return list;
} }
// Returns a collection of sidedefs that match a marked state
public List<Sidedef> GetMarkedSidedefs(bool mark)
{
List<Sidedef> list = new List<Sidedef>(sidedefs.Count >> 1);
foreach(Sidedef s in sidedefs) if(s.Marked == mark) list.Add(s);
return list;
}
// Returns a collection of sectors that match a marked state // Returns a collection of sectors that match a marked state
public List<Sector> GetMarkedSectors(bool mark) public List<Sector> GetMarkedSectors(bool mark)
{ {
@ -556,6 +637,17 @@ namespace CodeImp.DoomBuilder.Map
} }
} }
/// <summary>
/// This marks the sidedefs that make up the sectors with the matching mark
/// </summary>
public void MarkSidedefsFromSectors(bool matchmark, bool setmark)
{
foreach(Sidedef sd in sidedefs)
{
if(sd.Sector.Marked == matchmark) sd.Marked = setmark;
}
}
/// <summary> /// <summary>
/// Returns a collection of vertices that match a marked state on the linedefs /// Returns a collection of vertices that match a marked state on the linedefs
/// </summary> /// </summary>
@ -621,6 +713,49 @@ namespace CodeImp.DoomBuilder.Map
return list; return list;
} }
// This marks all selected geometry, including sidedefs from sectors
// Returns the number of selected elements
public void MarkAllSelectedGeometry(bool mark)
{
General.Map.Map.ClearAllMarks(!mark);
// Direct vertices
General.Map.Map.MarkSelectedVertices(true, mark);
// Direct linedefs
General.Map.Map.MarkSelectedLinedefs(true, mark);
// Vertices from linedefs
ICollection<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(mark);
foreach(Vertex v in verts) v.Marked = mark;
// Linedefs from vertices
ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(!mark, mark, !mark);
foreach(Linedef l in lines) l.Marked = mark;
// Mark sectors from linedefs (note: this must be the first to mark
// sectors, because this clears the sector marks!)
General.Map.Map.ClearMarkedSectors(mark);
foreach(Linedef l in General.Map.Map.Linedefs)
{
if(!l.Selected)
{
if(l.Front != null) l.Front.Sector.Marked = !mark;
if(l.Back != null) l.Back.Sector.Marked = !mark;
}
}
// Direct sectors
General.Map.Map.MarkSelectedSectors(true, mark);
// Direct things
General.Map.Map.MarkSelectedThings(true, mark);
// Sidedefs from linedefs
//General.Map.Map.MarkSidedefsFromLinedefs(true, mark);
General.Map.Map.MarkSidedefsFromSectors(true, mark);
}
#endregion #endregion
#region ================== Areas #region ================== Areas

View file

@ -43,6 +43,7 @@ namespace CodeImp.DoomBuilder.Windows
System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; System.Windows.Forms.ToolStripSeparator toolStripMenuItem4;
System.Windows.Forms.ToolStripSeparator toolStripSeparator2; System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
System.Windows.Forms.ToolStripSeparator toolStripSeparator7; System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.itemeditmodesseperator = new System.Windows.Forms.ToolStripSeparator(); this.itemeditmodesseperator = new System.Windows.Forms.ToolStripSeparator();
this.buttoneditmodesseperator = new System.Windows.Forms.ToolStripSeparator(); this.buttoneditmodesseperator = new System.Windows.Forms.ToolStripSeparator();
@ -62,6 +63,10 @@ namespace CodeImp.DoomBuilder.Windows
this.menuedit = new System.Windows.Forms.ToolStripMenuItem(); this.menuedit = new System.Windows.Forms.ToolStripMenuItem();
this.itemundo = new System.Windows.Forms.ToolStripMenuItem(); this.itemundo = new System.Windows.Forms.ToolStripMenuItem();
this.itemredo = new System.Windows.Forms.ToolStripMenuItem(); this.itemredo = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator();
this.itemcut = new System.Windows.Forms.ToolStripMenuItem();
this.itemcopy = new System.Windows.Forms.ToolStripMenuItem();
this.itempaste = new System.Windows.Forms.ToolStripMenuItem();
this.itemsnaptogrid = new System.Windows.Forms.ToolStripMenuItem(); this.itemsnaptogrid = new System.Windows.Forms.ToolStripMenuItem();
this.itemautomerge = new System.Windows.Forms.ToolStripMenuItem(); this.itemautomerge = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();
@ -96,6 +101,7 @@ namespace CodeImp.DoomBuilder.Windows
this.statusbar = new System.Windows.Forms.StatusStrip(); this.statusbar = new System.Windows.Forms.StatusStrip();
this.statuslabel = new System.Windows.Forms.ToolStripStatusLabel(); this.statuslabel = new System.Windows.Forms.ToolStripStatusLabel();
this.warninglabel = new System.Windows.Forms.ToolStripStatusLabel(); this.warninglabel = new System.Windows.Forms.ToolStripStatusLabel();
this.configlabel = new System.Windows.Forms.ToolStripStatusLabel();
this.gridlabel = new System.Windows.Forms.ToolStripStatusLabel(); this.gridlabel = new System.Windows.Forms.ToolStripStatusLabel();
this.buttongrid = new System.Windows.Forms.ToolStripDropDownButton(); this.buttongrid = new System.Windows.Forms.ToolStripDropDownButton();
this.itemgrid1024 = new System.Windows.Forms.ToolStripMenuItem(); this.itemgrid1024 = new System.Windows.Forms.ToolStripMenuItem();
@ -130,10 +136,6 @@ namespace CodeImp.DoomBuilder.Windows
this.processor = new System.Windows.Forms.Timer(this.components); this.processor = new System.Windows.Forms.Timer(this.components);
this.warningtimer = new System.Windows.Forms.Timer(this.components); this.warningtimer = new System.Windows.Forms.Timer(this.components);
this.warningflasher = new System.Windows.Forms.Timer(this.components); this.warningflasher = new System.Windows.Forms.Timer(this.components);
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator();
this.itemcut = new System.Windows.Forms.ToolStripMenuItem();
this.itemcopy = new System.Windows.Forms.ToolStripMenuItem();
this.itempaste = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
@ -148,6 +150,7 @@ namespace CodeImp.DoomBuilder.Windows
toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator(); toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
this.menumain.SuspendLayout(); this.menumain.SuspendLayout();
this.toolbar.SuspendLayout(); this.toolbar.SuspendLayout();
this.statusbar.SuspendLayout(); this.statusbar.SuspendLayout();
@ -230,6 +233,12 @@ namespace CodeImp.DoomBuilder.Windows
toolStripSeparator7.Name = "toolStripSeparator7"; toolStripSeparator7.Name = "toolStripSeparator7";
toolStripSeparator7.Size = new System.Drawing.Size(6, 25); toolStripSeparator7.Size = new System.Drawing.Size(6, 25);
// //
// toolStripSeparator12
//
toolStripSeparator12.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
toolStripSeparator12.Name = "toolStripSeparator12";
toolStripSeparator12.Size = new System.Drawing.Size(6, 23);
//
// itemeditmodesseperator // itemeditmodesseperator
// //
this.itemeditmodesseperator.Name = "itemeditmodesseperator"; this.itemeditmodesseperator.Name = "itemeditmodesseperator";
@ -401,6 +410,38 @@ namespace CodeImp.DoomBuilder.Windows
this.itemredo.Text = "Redo"; this.itemredo.Text = "Redo";
this.itemredo.Click += new System.EventHandler(this.InvokeTaggedAction); this.itemredo.Click += new System.EventHandler(this.InvokeTaggedAction);
// //
// toolStripMenuItem7
//
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
this.toolStripMenuItem7.Size = new System.Drawing.Size(162, 6);
//
// itemcut
//
this.itemcut.Image = global::CodeImp.DoomBuilder.Properties.Resources.Cut;
this.itemcut.Name = "itemcut";
this.itemcut.Size = new System.Drawing.Size(165, 22);
this.itemcut.Tag = "builder_cutselection";
this.itemcut.Text = "Cut";
this.itemcut.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// itemcopy
//
this.itemcopy.Image = global::CodeImp.DoomBuilder.Properties.Resources.Copy;
this.itemcopy.Name = "itemcopy";
this.itemcopy.Size = new System.Drawing.Size(165, 22);
this.itemcopy.Tag = "builder_copyselection";
this.itemcopy.Text = "Copy";
this.itemcopy.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// itempaste
//
this.itempaste.Image = global::CodeImp.DoomBuilder.Properties.Resources.Paste;
this.itempaste.Name = "itempaste";
this.itempaste.Size = new System.Drawing.Size(165, 22);
this.itempaste.Tag = "builder_pasteselection";
this.itempaste.Text = "Paste";
this.itempaste.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// itemsnaptogrid // itemsnaptogrid
// //
this.itemsnaptogrid.Checked = true; this.itemsnaptogrid.Checked = true;
@ -732,6 +773,8 @@ namespace CodeImp.DoomBuilder.Windows
this.statusbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.statusbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.statuslabel, this.statuslabel,
this.warninglabel, this.warninglabel,
this.configlabel,
toolStripSeparator12,
this.gridlabel, this.gridlabel,
this.buttongrid, this.buttongrid,
toolStripSeparator1, toolStripSeparator1,
@ -753,7 +796,7 @@ namespace CodeImp.DoomBuilder.Windows
this.statuslabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; this.statuslabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.statuslabel.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.statuslabel.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.statuslabel.Name = "statuslabel"; this.statuslabel.Name = "statuslabel";
this.statuslabel.Size = new System.Drawing.Size(571, 18); this.statuslabel.Size = new System.Drawing.Size(208, 18);
this.statuslabel.Spring = true; this.statuslabel.Spring = true;
this.statuslabel.Text = "Initializing user interface..."; this.statuslabel.Text = "Initializing user interface...";
this.statuslabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.statuslabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
@ -770,12 +813,22 @@ namespace CodeImp.DoomBuilder.Windows
this.warninglabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.warninglabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.warninglabel.Visible = false; this.warninglabel.Visible = false;
// //
// configlabel
//
this.configlabel.AutoSize = false;
this.configlabel.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.configlabel.Name = "configlabel";
this.configlabel.Size = new System.Drawing.Size(250, 18);
this.configlabel.Text = "ZDoom (Doom in Hexen Format)";
this.configlabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.configlabel.ToolTipText = "Current Game Configuration";
//
// gridlabel // gridlabel
// //
this.gridlabel.AutoSize = false; this.gridlabel.AutoSize = false;
this.gridlabel.AutoToolTip = true; this.gridlabel.AutoToolTip = true;
this.gridlabel.Name = "gridlabel"; this.gridlabel.Name = "gridlabel";
this.gridlabel.Size = new System.Drawing.Size(128, 18); this.gridlabel.Size = new System.Drawing.Size(62, 18);
this.gridlabel.Text = "32 mp"; this.gridlabel.Text = "32 mp";
this.gridlabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; this.gridlabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.gridlabel.TextImageRelation = System.Windows.Forms.TextImageRelation.Overlay; this.gridlabel.TextImageRelation = System.Windows.Forms.TextImageRelation.Overlay;
@ -1093,38 +1146,6 @@ namespace CodeImp.DoomBuilder.Windows
// //
this.warningflasher.Tick += new System.EventHandler(this.warningflasher_Tick); this.warningflasher.Tick += new System.EventHandler(this.warningflasher_Tick);
// //
// toolStripMenuItem7
//
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
this.toolStripMenuItem7.Size = new System.Drawing.Size(162, 6);
//
// itemcut
//
this.itemcut.Image = global::CodeImp.DoomBuilder.Properties.Resources.Cut;
this.itemcut.Name = "itemcut";
this.itemcut.Size = new System.Drawing.Size(165, 22);
this.itemcut.Tag = "builder_cutselection";
this.itemcut.Text = "Cut";
this.itemcut.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// itemcopy
//
this.itemcopy.Image = global::CodeImp.DoomBuilder.Properties.Resources.Copy;
this.itemcopy.Name = "itemcopy";
this.itemcopy.Size = new System.Drawing.Size(165, 22);
this.itemcopy.Tag = "builder_copyselection";
this.itemcopy.Text = "Copy";
this.itemcopy.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// itempaste
//
this.itempaste.Image = global::CodeImp.DoomBuilder.Properties.Resources.Paste;
this.itempaste.Name = "itempaste";
this.itempaste.Size = new System.Drawing.Size(165, 22);
this.itempaste.Tag = "builder_pasteselection";
this.itempaste.Text = "Paste";
this.itempaste.Click += new System.EventHandler(this.InvokeTaggedAction);
//
// MainForm // MainForm
// //
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
@ -1256,5 +1277,6 @@ namespace CodeImp.DoomBuilder.Windows
private System.Windows.Forms.ToolStripMenuItem itemcut; private System.Windows.Forms.ToolStripMenuItem itemcut;
private System.Windows.Forms.ToolStripMenuItem itemcopy; private System.Windows.Forms.ToolStripMenuItem itemcopy;
private System.Windows.Forms.ToolStripMenuItem itempaste; private System.Windows.Forms.ToolStripMenuItem itempaste;
private System.Windows.Forms.ToolStripStatusLabel configlabel;
} }
} }

View file

@ -379,6 +379,7 @@ namespace CodeImp.DoomBuilder.Windows
buttonzoom.Enabled = true; buttonzoom.Enabled = true;
gridlabel.Enabled = true; gridlabel.Enabled = true;
buttongrid.Enabled = true; buttongrid.Enabled = true;
configlabel.Text = General.Map.Config.Name;
} }
else else
{ {
@ -392,6 +393,7 @@ namespace CodeImp.DoomBuilder.Windows
buttonzoom.Enabled = false; buttonzoom.Enabled = false;
gridlabel.Enabled = false; gridlabel.Enabled = false;
buttongrid.Enabled = false; buttongrid.Enabled = false;
configlabel.Text = "";
} }
} }

View file

@ -159,6 +159,9 @@
<metadata name="toolStripSeparator7.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="toolStripSeparator7.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value> <value>False</value>
</metadata> </metadata>
<metadata name="toolStripSeparator12.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="menumain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="menumain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>