diff --git a/Documents/todo.txt b/Documents/todo.txt
index a8daefa3..c2ac42b9 100644
--- a/Documents/todo.txt
+++ b/Documents/todo.txt
@@ -27,3 +27,5 @@
- Make Plugin Development Kit
- 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)
diff --git a/Source/BuilderModes/BuilderModes.csproj b/Source/BuilderModes/BuilderModes.csproj
index 0b16ca53..9221126c 100644
--- a/Source/BuilderModes/BuilderModes.csproj
+++ b/Source/BuilderModes/BuilderModes.csproj
@@ -33,6 +33,7 @@
+
diff --git a/Source/BuilderModes/ClassicModes/BaseClassicMode.cs b/Source/BuilderModes/ClassicModes/BaseClassicMode.cs
new file mode 100644
index 00000000..ea69abe5
--- /dev/null
+++ b/Source/BuilderModes/ClassicModes/BaseClassicMode.cs
@@ -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
+ }
+}
diff --git a/Source/BuilderModes/ClassicModes/CurveLinedefsMode.cs b/Source/BuilderModes/ClassicModes/CurveLinedefsMode.cs
index 6daf9f84..d494304d 100644
--- a/Source/BuilderModes/ClassicModes/CurveLinedefsMode.cs
+++ b/Source/BuilderModes/ClassicModes/CurveLinedefsMode.cs
@@ -38,7 +38,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
[EditMode(DisplayName = "Curve Linedefs",
Volatile = true)]
- public sealed class CurveLinedefsMode : ClassicMode
+ public sealed class CurveLinedefsMode : BaseClassicMode
{
#region ================== Constants
@@ -48,9 +48,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables
- // Mode to return to
- private EditMode basemode;
-
// Collections
private ICollection selectedlines;
private ICollection unselectedlines;
@@ -60,9 +57,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties
// Just keep the base mode button checked
- public override string EditModeButtonName { get { return basemode.GetType().Name; } }
-
- internal EditMode BaseMode { get { return basemode; } }
+ public override string EditModeButtonName { get { return General.Map.PreviousStableMode.Name; } }
#endregion
@@ -71,8 +66,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Constructor
public CurveLinedefsMode(EditMode basemode)
{
- this.basemode = basemode;
-
// Make collections by selection
selectedlines = General.Map.Map.GetSelectedLinedefs(true);
unselectedlines = General.Map.Map.GetSelectedLinedefs(false);
@@ -95,6 +88,73 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Methods
+ // This generates the vertices to split the line with, from start to end
+ private List 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 points = new List(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
public override void OnCancel()
{
@@ -102,7 +162,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel();
// Return to base mode
- General.Map.ChangeMode(basemode);
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// Mode engages
@@ -161,70 +221,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.IsChanged = true;
// Return to base mode
- General.Map.ChangeMode(basemode);
- }
-
- // This generates the vertices to split the line with, from start to end
- private List 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 points = new List(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;
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// Redrawing display
diff --git a/Source/BuilderModes/ClassicModes/DragGeometryMode.cs b/Source/BuilderModes/ClassicModes/DragGeometryMode.cs
index 67fc67b4..136e76a8 100644
--- a/Source/BuilderModes/ClassicModes/DragGeometryMode.cs
+++ b/Source/BuilderModes/ClassicModes/DragGeometryMode.cs
@@ -36,16 +36,13 @@ using CodeImp.DoomBuilder.Editing;
namespace CodeImp.DoomBuilder.BuilderModes
{
- public abstract class DragGeometryMode : ClassicMode
+ public abstract class DragGeometryMode : BaseClassicMode
{
#region ================== Constants
#endregion
#region ================== Variables
-
- // Mode to return to
- private EditMode basemode;
// Mouse position on map where dragging started
private Vector2D dragstartmappos;
@@ -86,9 +83,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties
// Just keep the base mode button checked
- public override string EditModeButtonName { get { return basemode.GetType().Name; } }
-
- internal EditMode BaseMode { get { return basemode; } }
+ public override string EditModeButtonName { get { return General.Map.PreviousStableMode.Name; } }
#endregion
@@ -119,9 +114,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Initialize
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;
// Make list of selected vertices
@@ -291,7 +283,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel();
// Return to vertices mode
- General.Map.ChangeMode(basemode);
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// Mode engages
@@ -375,7 +367,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
protected override void OnEndEdit()
{
// Just return to base mode, Disengage will be called automatically.
- General.Map.ChangeMode(basemode);
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
base.OnEndEdit();
}
diff --git a/Source/BuilderModes/ClassicModes/DragLinedefsMode.cs b/Source/BuilderModes/ClassicModes/DragLinedefsMode.cs
index c294b249..5ab74ff0 100644
--- a/Source/BuilderModes/ClassicModes/DragLinedefsMode.cs
+++ b/Source/BuilderModes/ClassicModes/DragLinedefsMode.cs
@@ -68,7 +68,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DragLinedefsMode(Vector2D dragstartmappos)
{
// Mark what we are dragging
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedLinedefs(true, true);
ICollection verts = General.Map.Map.GetVerticesFromLinesMarks(true);
foreach(Vertex v in verts) v.Marked = true;
diff --git a/Source/BuilderModes/ClassicModes/DragSectorsMode.cs b/Source/BuilderModes/ClassicModes/DragSectorsMode.cs
index cfa79dc7..58b17b07 100644
--- a/Source/BuilderModes/ClassicModes/DragSectorsMode.cs
+++ b/Source/BuilderModes/ClassicModes/DragSectorsMode.cs
@@ -68,7 +68,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DragSectorsMode(Vector2D dragstartmappos)
{
// Mark what we are dragging
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedLinedefs(true, true);
ICollection verts = General.Map.Map.GetVerticesFromLinesMarks(true);
foreach(Vertex v in verts) v.Marked = true;
diff --git a/Source/BuilderModes/ClassicModes/DragThingsMode.cs b/Source/BuilderModes/ClassicModes/DragThingsMode.cs
index 4cf502d8..6d513868 100644
--- a/Source/BuilderModes/ClassicModes/DragThingsMode.cs
+++ b/Source/BuilderModes/ClassicModes/DragThingsMode.cs
@@ -45,7 +45,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
[EditMode(DisplayName = "Things",
Volatile = true)]
- public sealed class DragThingsMode : ClassicMode
+ public sealed class DragThingsMode : BaseClassicMode
{
#region ================== Constants
@@ -104,7 +104,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Cursor.Current = Cursors.AppStarting;
// Mark what we are dragging
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedThings(true, true);
// Get selected things
diff --git a/Source/BuilderModes/ClassicModes/DragVerticesMode.cs b/Source/BuilderModes/ClassicModes/DragVerticesMode.cs
index e1865ab6..97facacb 100644
--- a/Source/BuilderModes/ClassicModes/DragVerticesMode.cs
+++ b/Source/BuilderModes/ClassicModes/DragVerticesMode.cs
@@ -65,7 +65,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DragVerticesMode(Vertex dragitem, Vector2D dragstartmappos)
{
// Mark what we are dragging
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true);
// Initialize
diff --git a/Source/BuilderModes/ClassicModes/DrawGeometryMode.cs b/Source/BuilderModes/ClassicModes/DrawGeometryMode.cs
index b0286b1d..1b682aea 100644
--- a/Source/BuilderModes/ClassicModes/DrawGeometryMode.cs
+++ b/Source/BuilderModes/ClassicModes/DrawGeometryMode.cs
@@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
SwitchAction = "drawlinesmode",
Volatile = true)]
- public class DrawGeometryMode : ClassicMode
+ public class DrawGeometryMode : BaseClassicMode
{
#region ================== Structures
@@ -61,9 +61,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables
- // Mode to return to
- private EditMode basemode;
-
// Drawing points
private List points;
private List labels;
@@ -82,9 +79,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties
// Just keep the base mode button checked
- public override string EditModeButtonName { get { return basemode.GetType().Name; } }
-
- internal EditMode BaseMode { get { return basemode; } }
+ public override string EditModeButtonName { get { return General.Map.PreviousStableMode.Name; } }
#endregion
@@ -94,13 +89,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
public DrawGeometryMode()
{
// Initialize
- this.basemode = General.Map.Mode;
points = new List();
labels = new List();
// No selection in this mode
General.Map.Map.ClearAllSelected();
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
// We have no destructor
GC.SuppressFinalize(this);
@@ -125,6 +119,215 @@ namespace CodeImp.DoomBuilder.BuilderModes
#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 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
public override void OnEngage()
{
@@ -142,9 +345,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel();
// Return to original mode
- Type t = basemode.GetType();
- basemode = (EditMode)Activator.CreateInstance(t);
- General.Map.ChangeMode(basemode);
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// Accepted
@@ -577,28 +778,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Cursor.Current = Cursors.Default;
// Return to original mode
- Type t = basemode.GetType();
- 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;
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// This redraws the display
@@ -623,166 +803,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
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 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
public override void OnMouseMove(MouseEventArgs e)
{
@@ -790,31 +810,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
Update();
}
- // This draws a point at a specific location
- public void DrawPointAt(Vector2D pos, bool stitch)
+ // When a key is released
+ public override void OnKeyUp(KeyEventArgs e)
{
- 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();
- }
- }
+ 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
// Drawing a point
[BeginAction("drawpoint")]
@@ -850,22 +864,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
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
}
}
diff --git a/Source/BuilderModes/ClassicModes/EditSelectionMode.cs b/Source/BuilderModes/ClassicModes/EditSelectionMode.cs
index 357d6ce6..f1870676 100644
--- a/Source/BuilderModes/ClassicModes/EditSelectionMode.cs
+++ b/Source/BuilderModes/ClassicModes/EditSelectionMode.cs
@@ -43,7 +43,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
SwitchAction = "editselectionmode", // Action name used to switch to this mode
Volatile = true)]
- public class EditSelectionMode : ClassicMode
+ public class EditSelectionMode : BaseClassicMode
{
#region ================== Enums
@@ -83,8 +83,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables
- // Mode to return to
- private EditMode basemode;
+ // Mode switching
private bool modealreadyswitching = false;
// Highlighted vertex
@@ -133,7 +132,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties
// 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
@@ -143,11 +142,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public EditSelectionMode()
{
// Initialize
- basemode = General.Map.Mode;
mode = ModifyMode.None;
-
- // TEST:
- rotation = Angle2D.PI2 * 0;// 0.02f;
}
// 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 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 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(selectedvertices.Count);
- thingpos = new List(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();
- selectedthings = new List();
- 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
#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
protected void Highlight(Vertex v)
{
@@ -1031,5 +575,456 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
#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 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 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(selectedvertices.Count);
+ thingpos = new List(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();
+ selectedthings = new List();
+ 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
}
}
diff --git a/Source/BuilderModes/ClassicModes/FindReplaceMode.cs b/Source/BuilderModes/ClassicModes/FindReplaceMode.cs
index 9d1d351f..1ced964d 100644
--- a/Source/BuilderModes/ClassicModes/FindReplaceMode.cs
+++ b/Source/BuilderModes/ClassicModes/FindReplaceMode.cs
@@ -39,8 +39,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
[EditMode(DisplayName = "Find & Replace",
SwitchAction = "findmode",
Volatile = true)]
-
- public sealed class FindReplaceMode : ClassicMode
+
+ public sealed class FindReplaceMode : BaseClassicMode
{
#region ================== Constants
@@ -48,41 +48,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables
- // Mode to return to
- private EditMode basemode;
-
#endregion
#region ================== Properties
- internal EditMode BaseMode { get { return basemode; } }
-
#endregion
#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
- #region ================== Methods
+ #region ================== Events
// Cancelled
public override void OnCancel()
@@ -91,7 +67,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.OnCancel();
// Return to base mode
- General.Map.ChangeMode(basemode.GetType().Name);
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// Mode engages
@@ -127,7 +103,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.IsChanged = true;
// Return to base mode
- General.Map.ChangeMode(basemode);
+ General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
}
// Redrawing display
diff --git a/Source/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/BuilderModes/ClassicModes/LinedefsMode.cs
index be6c258a..b83e2532 100644
--- a/Source/BuilderModes/ClassicModes/LinedefsMode.cs
+++ b/Source/BuilderModes/ClassicModes/LinedefsMode.cs
@@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "LinesMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 100)] // Position of the button (lower is more to the left)
- public class LinedefsMode : ClassicMode
+ public class LinedefsMode : BaseClassicMode
{
#region ================== Constants
@@ -70,28 +70,108 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Constructor / Disposer
- // Constructor
- public LinedefsMode()
- {
- }
-
- // Disposer
- public override void Dispose()
- {
- // Not already disposed?
- if(!isdisposed)
- {
- // Clean up
-
- // Dispose base
- base.Dispose();
- }
- }
-
#endregion
#region ================== Methods
+ // This highlights a new item
+ protected void Highlight(Linedef l)
+ {
+ bool completeredraw = false;
+ LinedefActionInfo action = null;
+
+ // 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(l != null)
+ highlightasso.Set(l.Tag, UniversalType.LinedefTag);
+ else
+ highlightasso.Set(0, 0);
+
+ // New association highlights something?
+ if((l != null) && (l.Tag > 0)) completeredraw = true;
+
+ if(l != null)
+ {
+ // Check if we can find the linedefs action
+ if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action))
+ action = General.Map.Config.LinedefActions[l.Action];
+ }
+
+ // Determine linedef associations
+ for(int i = 0; i < Linedef.NUM_ARGS; i++)
+ {
+ // Previous association highlights something?
+ if((association[i].type == UniversalType.SectorTag) ||
+ (association[i].type == UniversalType.LinedefTag) ||
+ (association[i].type == UniversalType.ThingTag)) completeredraw = true;
+
+ // Make new association
+ if(action != null)
+ association[i].Set(l.Args[i], action.Args[i].Type);
+ else
+ association[i].Set(0, 0);
+
+ // New association highlights something?
+ if((association[i].type == UniversalType.SectorTag) ||
+ (association[i].type == UniversalType.LinedefTag) ||
+ (association[i].type == UniversalType.ThingTag)) completeredraw = true;
+ }
+
+ // If we're changing associations, then we
+ // need to redraw the entire display
+ if(completeredraw)
+ {
+ // Set new highlight and redraw completely
+ highlighted = l;
+ General.Interface.RedrawDisplay();
+ }
+ else
+ {
+ // Update display
+ if(renderer.StartPlotter(false))
+ {
+ // Undraw previous highlight
+ if((highlighted != null) && !highlighted.IsDisposed)
+ {
+ renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted));
+ renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
+ renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
+ }
+
+ // Set new highlight
+ highlighted = l;
+
+ // Render highlighted item
+ if((highlighted != null) && !highlighted.IsDisposed)
+ {
+ renderer.PlotLinedef(highlighted, General.Colors.Highlight);
+ renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
+ renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
+ }
+
+ // Done
+ renderer.Finish();
+ renderer.Present();
+ }
+ }
+
+ // Show highlight info
+ if((highlighted != null) && !highlighted.IsDisposed)
+ General.Interface.ShowLinedefInfo(highlighted);
+ else
+ General.Interface.HideInfo();
+ }
+
+ #endregion
+
+ #region ================== Events
+
// Cancel mode
public override void OnCancel()
{
@@ -108,7 +188,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.SetPresentation(Presentation.Standard);
// Convert geometry selection to linedefs selection
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true);
ICollection lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in lines) l.Selected = true;
@@ -173,100 +253,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Present();
}
- // This highlights a new item
- protected void Highlight(Linedef l)
- {
- bool completeredraw = false;
- LinedefActionInfo action = null;
-
- // 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(l != null)
- highlightasso.Set(l.Tag, UniversalType.LinedefTag);
- else
- highlightasso.Set(0, 0);
-
- // New association highlights something?
- if((l != null) && (l.Tag > 0)) completeredraw = true;
-
- if(l != null)
- {
- // Check if we can find the linedefs action
- if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action))
- action = General.Map.Config.LinedefActions[l.Action];
- }
-
- // Determine linedef associations
- for(int i = 0; i < Linedef.NUM_ARGS; i++)
- {
- // Previous association highlights something?
- if((association[i].type == UniversalType.SectorTag) ||
- (association[i].type == UniversalType.LinedefTag) ||
- (association[i].type == UniversalType.ThingTag)) completeredraw = true;
-
- // Make new association
- if(action != null)
- association[i].Set(l.Args[i], action.Args[i].Type);
- else
- association[i].Set(0, 0);
-
- // New association highlights something?
- if((association[i].type == UniversalType.SectorTag) ||
- (association[i].type == UniversalType.LinedefTag) ||
- (association[i].type == UniversalType.ThingTag)) completeredraw = true;
- }
-
- // If we're changing associations, then we
- // need to redraw the entire display
- if(completeredraw)
- {
- // Set new highlight and redraw completely
- highlighted = l;
- General.Interface.RedrawDisplay();
- }
- else
- {
- // Update display
- if(renderer.StartPlotter(false))
- {
- // Undraw previous highlight
- if((highlighted != null) && !highlighted.IsDisposed)
- {
- renderer.PlotLinedef(highlighted, renderer.DetermineLinedefColor(highlighted));
- renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
- renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
- }
-
- // Set new highlight
- highlighted = l;
-
- // Render highlighted item
- if((highlighted != null) && !highlighted.IsDisposed)
- {
- renderer.PlotLinedef(highlighted, General.Colors.Highlight);
- renderer.PlotVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start));
- renderer.PlotVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End));
- }
-
- // Done
- renderer.Finish();
- renderer.Present();
- }
- }
-
- // Show highlight info
- if((highlighted != null) && !highlighted.IsDisposed)
- General.Interface.ShowLinedefInfo(highlighted);
- else
- General.Interface.HideInfo();
- }
-
// Selection
protected override void OnSelect()
{
@@ -474,17 +460,31 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Present();
}
}
-
+
// When copying
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
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
diff --git a/Source/BuilderModes/ClassicModes/MakeSectorMode.cs b/Source/BuilderModes/ClassicModes/MakeSectorMode.cs
index 22287639..6c96a6fb 100644
--- a/Source/BuilderModes/ClassicModes/MakeSectorMode.cs
+++ b/Source/BuilderModes/ClassicModes/MakeSectorMode.cs
@@ -43,7 +43,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "NewSector2.png", // Image resource name for the button
ButtonOrder = int.MinValue + 202)] // Position of the button (lower is more to the left)
- public class MakeSectorMode : ClassicMode
+ public class MakeSectorMode : BaseClassicMode
{
#region ================== Constants
@@ -100,6 +100,111 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Methods
+ // This draws the geometry
+ private void DrawGeometry()
+ {
+ // Render lines and vertices
+ if(renderer.StartPlotter(true))
+ {
+ renderer.PlotLinedefSet(General.Map.Map.Linedefs);
+
+ // Render highlight
+ if(alllines != null)
+ {
+ foreach(Linedef l in alllines) renderer.PlotLinedef(l, General.Colors.Highlight);
+ }
+
+ renderer.PlotVerticesSet(General.Map.Map.Vertices);
+ renderer.Finish();
+ }
+ }
+
+ // This draws the overlay
+ private void DrawOverlay()
+ {
+ // Redraw overlay
+ if(renderer.StartOverlay(true))
+ {
+ if((flashpolygon != null) && (flashintensity > 0.0f))
+ {
+ renderer.RenderGeometry(flashpolygon, null, true);
+ }
+
+ renderer.Finish();
+ }
+ }
+
+ // This highlights a new region
+ protected void Highlight(bool buttonspressed)
+ {
+ LinedefSide newnearest;
+
+ // Mouse inside?
+ if(mouseinside)
+ {
+ // Highlighting from a new sidedef?
+ Linedef nl = General.Map.Map.NearestLinedef(mousemappos);
+ float side = nl.SideOfLine(mousemappos);
+ newnearest = new LinedefSide(nl, (side <= 0.0f));
+ if(newnearest != nearestside)
+ {
+ // Only change when buttons are not pressed
+ if(!buttonspressed || (editside == newnearest))
+ {
+ // Find new sector
+ General.Interface.SetCursor(Cursors.AppStarting);
+ nearestside = newnearest;
+ allsides = SectorTools.FindPotentialSectorAt(mousemappos);
+ if(allsides != null)
+ {
+ alllines = new List(allsides.Count);
+ foreach(LinedefSide sd in allsides) alllines.Add(sd.Line);
+ }
+ else
+ {
+ alllines = null;
+ }
+ General.Interface.SetCursor(Cursors.Default);
+ }
+ else
+ {
+ // Don't highlight this one
+ nearestside = null;
+ allsides = null;
+ alllines = null;
+ }
+
+ // Redraw overlay
+ DrawGeometry();
+ renderer.Present();
+ }
+ }
+ else
+ {
+ // No valid region
+ nearestside = null;
+ allsides = null;
+ alllines = null;
+
+ // Redraw overlay
+ DrawGeometry();
+ renderer.Present();
+ }
+ }
+
+ // Start select
+ protected override void OnSelect()
+ {
+ // Select pressed in this mode
+ selectpressed = true;
+ editside = nearestside;
+ base.OnEdit();
+ }
+
+ #endregion
+
+ #region ================== Events
+
// Cancel mode
public override void OnCancel()
{
@@ -171,107 +276,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Present();
}
- // This draws the geometry
- private void DrawGeometry()
- {
- // Render lines and vertices
- if(renderer.StartPlotter(true))
- {
- renderer.PlotLinedefSet(General.Map.Map.Linedefs);
-
- // Render highlight
- if(alllines != null)
- {
- foreach(Linedef l in alllines) renderer.PlotLinedef(l, General.Colors.Highlight);
- }
-
- renderer.PlotVerticesSet(General.Map.Map.Vertices);
- renderer.Finish();
- }
- }
-
- // This draws the overlay
- private void DrawOverlay()
- {
- // Redraw overlay
- if(renderer.StartOverlay(true))
- {
- if((flashpolygon != null) && (flashintensity > 0.0f))
- {
- renderer.RenderGeometry(flashpolygon, null, true);
- }
-
- renderer.Finish();
- }
- }
-
- // This highlights a new region
- protected void Highlight(bool buttonspressed)
- {
- LinedefSide newnearest;
-
- // Mouse inside?
- if(mouseinside)
- {
- // Highlighting from a new sidedef?
- Linedef nl = General.Map.Map.NearestLinedef(mousemappos);
- float side = nl.SideOfLine(mousemappos);
- newnearest = new LinedefSide(nl, (side <= 0.0f));
- if(newnearest != nearestside)
- {
- // Only change when buttons are not pressed
- if(!buttonspressed || (editside == newnearest))
- {
- // Find new sector
- General.Interface.SetCursor(Cursors.AppStarting);
- nearestside = newnearest;
- allsides = SectorTools.FindPotentialSectorAt(mousemappos);
- if(allsides != null)
- {
- alllines = new List(allsides.Count);
- foreach(LinedefSide sd in allsides) alllines.Add(sd.Line);
- }
- else
- {
- alllines = null;
- }
- General.Interface.SetCursor(Cursors.Default);
- }
- else
- {
- // Don't highlight this one
- nearestside = null;
- allsides = null;
- alllines = null;
- }
-
- // Redraw overlay
- DrawGeometry();
- renderer.Present();
- }
- }
- else
- {
- // No valid region
- nearestside = null;
- allsides = null;
- alllines = null;
-
- // Redraw overlay
- DrawGeometry();
- renderer.Present();
- }
- }
-
- // Start select
- protected override void OnSelect()
- {
- // Select pressed in this mode
- selectpressed = true;
- editside = nearestside;
- base.OnEdit();
- }
-
// Done selecting
protected override void OnEndSelect()
{
diff --git a/Source/BuilderModes/ClassicModes/SectorsMode.cs b/Source/BuilderModes/ClassicModes/SectorsMode.cs
index c3703bd5..d1d707cd 100644
--- a/Source/BuilderModes/ClassicModes/SectorsMode.cs
+++ b/Source/BuilderModes/ClassicModes/SectorsMode.cs
@@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "SectorsMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 200)] // Position of the button (lower is more to the left)
- public class SectorsMode : ClassicMode
+ public class SectorsMode : BaseClassicMode
{
#region ================== Constants
@@ -101,31 +101,105 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Methods
- // This clears the selection
- [BeginAction("clearselection", BaseAction = true)]
- public void ClearSelection()
+ // Support function for joining and merging sectors
+ private void JoinMergeSectors(bool removelines)
{
- // Clear selection
- General.Map.Map.ClearAllSelected();
+ // Remove lines in betwen joining sectors?
+ if(removelines)
+ {
+ // Go for all selected linedefs
+ ICollection 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
- General.Interface.RedrawDisplay();
- }
-
- // When undo is used
- [EndAction("undo", BaseAction = true)]
- public void Undo()
- {
- // Clear ordered selection
- orderedselection.Clear();
+ // Join all selected sectors with the first
+ for(int i = 1; i < orderedselection.Count; i++)
+ orderedselection[i].Join(orderedselection[0]);
}
- // When redo is used
- [EndAction("redo", BaseAction = true)]
- public void Redo()
+ // This highlights a new item
+ protected void Highlight(Sector s)
{
- // Clear ordered selection
- orderedselection.Clear();
+ 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();
}
// This selectes or deselects a sector
@@ -161,6 +235,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
+
+ #endregion
+
+ #region ================== Events
// Cancel mode
public override void OnCancel()
@@ -178,7 +256,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.SetPresentation(Presentation.Standard);
// Convert geometry selection to sectors only
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true);
ICollection lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in lines) l.Selected = true;
@@ -257,78 +335,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
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
protected override void OnSelect()
{
@@ -588,6 +594,50 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Present();
}
}
+
+ // 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
@@ -721,35 +771,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
- // Support function for joining and merging sectors
- private void JoinMergeSectors(bool removelines)
+ // This clears the selection
+ [BeginAction("clearselection", BaseAction = true)]
+ public void ClearSelection()
{
- // Remove lines in betwen joining sectors?
- if(removelines)
- {
- // Go for all selected linedefs
- ICollection 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
- for(int i = 1; i < orderedselection.Count; i++)
- orderedselection[i].Join(orderedselection[0]);
- }
+ // Clear selection
+ General.Map.Map.ClearAllSelected();
+ // Redraw
+ General.Interface.RedrawDisplay();
+ }
+
#endregion
}
}
diff --git a/Source/BuilderModes/ClassicModes/ThingsMode.cs b/Source/BuilderModes/ClassicModes/ThingsMode.cs
index 7b335937..62faf46f 100644
--- a/Source/BuilderModes/ClassicModes/ThingsMode.cs
+++ b/Source/BuilderModes/ClassicModes/ThingsMode.cs
@@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "ThingsMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 300)] // Position of the button (lower is more to the left)
- public class ThingsMode : ClassicMode
+ public class ThingsMode : BaseClassicMode
{
#region ================== Constants
@@ -70,24 +70,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Constructor / Disposer
- // Constructor
- public ThingsMode()
- {
- }
-
- // Disposer
- public override void Dispose()
- {
- // Not already disposed?
- if(!isdisposed)
- {
- // Clean up
-
- // Dispose base
- base.Dispose();
- }
- }
-
#endregion
#region ================== Methods
@@ -108,7 +90,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.SetPresentation(Presentation.Things);
// Convert geometry selection to linedefs selection
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedVertices(true, true);
ICollection lines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
foreach(Linedef l in lines) l.Selected = true;
@@ -456,6 +438,32 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.Present();
}
}
+
+ // 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
diff --git a/Source/BuilderModes/ClassicModes/VerticesMode.cs b/Source/BuilderModes/ClassicModes/VerticesMode.cs
index 48f84d99..070618f7 100644
--- a/Source/BuilderModes/ClassicModes/VerticesMode.cs
+++ b/Source/BuilderModes/ClassicModes/VerticesMode.cs
@@ -42,7 +42,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
ButtonImage = "VerticesMode.png", // Image resource name for the button
ButtonOrder = int.MinValue + 0)] // Position of the button (lower is more to the left)
- public class VerticesMode : ClassicMode
+ public class VerticesMode : BaseClassicMode
{
#region ================== Constants
@@ -67,24 +67,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Constructor / Disposer
- // Constructor
- public VerticesMode()
- {
- }
-
- // Disposer
- public override void Dispose()
- {
- // Not already disposed?
- if(!isdisposed)
- {
- // Clean up
-
- // Dispose base
- base.Dispose();
- }
- }
-
#endregion
#region ================== Methods
@@ -107,7 +89,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
renderer.SetPresentation(Presentation.Standard);
// Convert geometry selection to vertices only
- General.Map.Map.ClearAllMarks();
+ General.Map.Map.ClearAllMarks(false);
General.Map.Map.MarkSelectedLinedefs(true, true);
General.Map.Map.MarkSelectedSectors(true, 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
#region ================== Actions
@@ -463,7 +471,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Interface.RedrawDisplay();
}
}
-
+
#endregion
}
}
diff --git a/Source/BuilderModes/General/BuilderPlug.cs b/Source/BuilderModes/General/BuilderPlug.cs
index 26e2f38b..de2b381e 100644
--- a/Source/BuilderModes/General/BuilderPlug.cs
+++ b/Source/BuilderModes/General/BuilderPlug.cs
@@ -121,7 +121,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#endregion
#region ================== Tools
-
+
// This renders the associated sectors/linedefs with the indication color
public void PlotAssociations(IRenderer2D renderer, Association asso)
{
@@ -143,6 +143,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
+
// This renders the associated things with the indication color
public void RenderAssociations(IRenderer2D renderer, Association asso)
@@ -159,6 +160,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
+
// This renders the associated sectors/linedefs with the indication color
public void PlotReverseAssociations(IRenderer2D renderer, Association asso)
@@ -181,6 +183,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
}
+
// This renders the associated things with the indication color
public void RenderReverseAssociations(IRenderer2D renderer, Association asso)
diff --git a/Source/BuilderModes/Interface/MenusForm.cs b/Source/BuilderModes/Interface/MenusForm.cs
index 1082cd6e..9aeb91d6 100644
--- a/Source/BuilderModes/Interface/MenusForm.cs
+++ b/Source/BuilderModes/Interface/MenusForm.cs
@@ -117,16 +117,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This shows the menu for the current editing 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
- if(mode is DragGeometryMode) mode = (mode as DragGeometryMode).BaseMode;
- if(mode is DragThingsMode) mode = (mode as DragThingsMode).BaseMode;
- if(mode is DrawGeometryMode) mode = (mode as DrawGeometryMode).BaseMode;
- if(mode is CurveLinedefsMode) mode = (mode as CurveLinedefsMode).BaseMode;
+ if((mode is DragGeometryMode) || (mode is DragThingsMode) ||
+ (mode is DrawGeometryMode) || (mode is CurveLinedefsMode))
+ sourcemode = General.Map.PreviousStableMode;
// Final decision
- if(mode is LinedefsMode) HideAllMenusExcept(linedefsmenu);
- else if(mode is SectorsMode) HideAllMenusExcept(sectorsmenu);
- else if(mode is ThingsMode) HideAllMenusExcept(thingsmenu);
+ if(sourcemode == typeof(LinedefsMode)) HideAllMenusExcept(linedefsmenu);
+ else if(sourcemode == typeof(SectorsMode)) HideAllMenusExcept(sectorsmenu);
+ else if(sourcemode == typeof(ThingsMode)) HideAllMenusExcept(thingsmenu);
else HideAllMenus();
}
diff --git a/Source/Config/GameConfiguration.cs b/Source/Config/GameConfiguration.cs
index 1918959c..3e6fa3b3 100644
--- a/Source/Config/GameConfiguration.cs
+++ b/Source/Config/GameConfiguration.cs
@@ -43,6 +43,7 @@ namespace CodeImp.DoomBuilder.Config
private Configuration cfg;
// General settings
+ private string configname;
private string enginename;
private float defaulttexturescale;
private float defaultflatscale;
@@ -102,6 +103,7 @@ namespace CodeImp.DoomBuilder.Config
#region ================== Properties
// General settings
+ public string Name { get { return configname; } }
public string EngineName { get { return enginename; } }
public float DefaultTextureScale { get { return defaulttexturescale; } }
public float DefaultFlatScale { get { return defaultflatscale; } }
@@ -184,6 +186,7 @@ namespace CodeImp.DoomBuilder.Config
this.skills = new List();
// Read general settings
+ configname = cfg.ReadSetting("game", "");
enginename = cfg.ReadSetting("engine", "");
defaulttexturescale = cfg.ReadSetting("defaulttexturescale", 1f);
defaultflatscale = cfg.ReadSetting("defaultflatscale", 1f);
diff --git a/Source/Editing/CopyPasteManager.cs b/Source/Editing/CopyPasteManager.cs
index aa2df0f2..da03dbd7 100644
--- a/Source/Editing/CopyPasteManager.cs
+++ b/Source/Editing/CopyPasteManager.cs
@@ -96,22 +96,25 @@ namespace CodeImp.DoomBuilder.Editing
// that need to be copied.
if(General.Map.Mode.OnCopyBegin())
{
- MapSet copyset = new MapSet();
-
- // Copy all data over
- copyset = General.Map.Map.Clone();
+ // Get all marked elements
+ ICollection verts = General.Map.Map.GetMarkedVertices(true);
+ ICollection sides = General.Map.Map.GetMarkedSidedefs(true);
+ ICollection sectors = General.Map.Map.GetMarkedSectors(true);
+ ICollection lines = General.Map.Map.GetMarkedLinedefs(true);
+ ICollection things = General.Map.Map.GetMarkedThings(true);
// Write data to stream
MemoryStream memstream = new MemoryStream();
UniversalStreamWriter writer = new UniversalStreamWriter();
writer.RememberCustomTypes = false;
- writer.Write(copyset, memstream, null);
+ writer.Write(verts, lines, sides, sectors, things, memstream, null);
// Set on clipboard
Clipboard.SetData(CLIPBOARD_DATA_FORMAT, memstream);
// Done
memstream.Dispose();
+ General.Map.Mode.OnCopyEnd();
return true;
}
else
@@ -124,21 +127,36 @@ namespace CodeImp.DoomBuilder.Editing
// This performs the paste. Returns false when paste was cancelled.
private bool DoPasteSelection()
{
- // Ask the editing mode to prepare selection for pasting.
- if(General.Map.Mode.OnPasteBegin())
+ // Anything to paste?
+ if(Clipboard.ContainsData(CLIPBOARD_DATA_FORMAT))
{
- // TODO: Do the paste
-
- if(Clipboard.ContainsData(CLIPBOARD_DATA_FORMAT))
+ // Ask the editing mode to prepare selection for pasting.
+ if(General.Map.Mode.OnPasteBegin())
{
+ // Read from clipboard
Stream memstream = (Stream)Clipboard.GetData(CLIPBOARD_DATA_FORMAT);
memstream.Seek(0, SeekOrigin.Begin);
- StreamReader reader = new StreamReader(memstream, Encoding.ASCII);
- //File.WriteAllText("C:\\Test.txt", reader.ReadToEnd());
- memstream.Dispose();
- }
- return true;
+ // 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;
+ }
+ else
+ {
+ General.MessageBeep(MessageBeepType.Warning);
+ return false;
+ }
}
else
{
diff --git a/Source/Editing/EditMode.cs b/Source/Editing/EditMode.cs
index 17c41e76..0b0e0a35 100644
--- a/Source/Editing/EditMode.cs
+++ b/Source/Editing/EditMode.cs
@@ -168,9 +168,20 @@ namespace CodeImp.DoomBuilder.Editing
// The edit mode should mark all vertices, lines and sectors
// that need to be copied.
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.
- 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
public virtual void OnMouseClick(MouseEventArgs e) { }
diff --git a/Source/Editing/UndoManager.cs b/Source/Editing/UndoManager.cs
index 07846d57..ea717404 100644
--- a/Source/Editing/UndoManager.cs
+++ b/Source/Editing/UndoManager.cs
@@ -218,42 +218,46 @@ namespace CodeImp.DoomBuilder.Editing
Cursor oldcursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
- // Cancel volatile mode, if any
- // This returns false when mode was not volatile
- if(!General.CancelVolatileMode())
+ // Call UndoBegin event
+ if(General.Map.Mode.OnUndoBegin())
{
- // Anything to undo?
- if(undos.Count > 0)
+ // Cancel volatile mode, if any
+ // This returns false when mode was not volatile
+ if(!General.CancelVolatileMode())
{
- // Get undo snapshot
- u = undos[0];
- undos.RemoveAt(0);
+ // Anything to undo?
+ if(undos.Count > 0)
+ {
+ // Get undo snapshot
+ u = undos[0];
+ undos.RemoveAt(0);
- General.WriteLogLine("Performing undo \"" + u.description + "\", Ticket ID " + u.ticketid + "...");
+ General.WriteLogLine("Performing undo \"" + u.description + "\", Ticket ID " + u.ticketid + "...");
- // Make a snapshot for redo
- r = new UndoSnapshot(u, General.Map.Map.Clone());
+ // Make a snapshot for redo
+ r = new UndoSnapshot(u, General.Map.Map.Clone());
- // Put it on the stack
- redos.Insert(0, r);
- LimitUndoRedoLevel(redos);
+ // Put it on the stack
+ redos.Insert(0, r);
+ LimitUndoRedoLevel(redos);
- // Reset grouping
- lastgroup = UndoGroup.None;
+ // Reset grouping
+ lastgroup = UndoGroup.None;
- // Remove selection
- u.map.ClearAllMarks();
- u.map.ClearAllSelected();
+ // Remove selection
+ u.map.ClearAllMarks(false);
+ u.map.ClearAllSelected();
- // Change map set
- General.Map.ChangeMapSet(u.map);
+ // Change map set
+ General.Map.ChangeMapSet(u.map);
- // Update
- General.MainWindow.RedrawDisplay();
- General.MainWindow.UpdateInterface();
+ // Update
+ General.MainWindow.RedrawDisplay();
+ General.MainWindow.UpdateInterface();
+ }
}
}
-
+
Cursor.Current = oldcursor;
}
@@ -265,38 +269,42 @@ namespace CodeImp.DoomBuilder.Editing
Cursor oldcursor = Cursor.Current;
Cursor.Current = Cursors.WaitCursor;
- // Cancel volatile mode, if any
- General.CancelVolatileMode();
-
- // Anything to redo?
- if(redos.Count > 0)
+ // Call RedoBegin event
+ if(General.Map.Mode.OnRedoBegin())
{
- // Get redo snapshot
- r = redos[0];
- redos.RemoveAt(0);
+ // Cancel volatile mode, if any
+ General.CancelVolatileMode();
- General.WriteLogLine("Performing redo \"" + r.description + "\", Ticket ID " + r.ticketid + "...");
+ // Anything to redo?
+ if(redos.Count > 0)
+ {
+ // Get redo snapshot
+ r = redos[0];
+ redos.RemoveAt(0);
- // Make a snapshot for undo
- u = new UndoSnapshot(r, General.Map.Map.Clone());
+ General.WriteLogLine("Performing redo \"" + r.description + "\", Ticket ID " + r.ticketid + "...");
- // Put it on the stack
- undos.Insert(0, u);
- LimitUndoRedoLevel(undos);
-
- // Reset grouping
- lastgroup = UndoGroup.None;
+ // Make a snapshot for undo
+ u = new UndoSnapshot(r, General.Map.Map.Clone());
- // Remove selection
- r.map.ClearAllMarks();
- r.map.ClearAllSelected();
+ // Put it on the stack
+ undos.Insert(0, u);
+ LimitUndoRedoLevel(undos);
- // Change map set
- General.Map.ChangeMapSet(r.map);
+ // Reset grouping
+ lastgroup = UndoGroup.None;
- // Update
- General.MainWindow.RedrawDisplay();
- General.MainWindow.UpdateInterface();
+ // Remove selection
+ r.map.ClearAllMarks(false);
+ r.map.ClearAllSelected();
+
+ // Change map set
+ General.Map.ChangeMapSet(r.map);
+
+ // Update
+ General.MainWindow.RedrawDisplay();
+ General.MainWindow.UpdateInterface();
+ }
}
Cursor.Current = oldcursor;
diff --git a/Source/General/MapManager.cs b/Source/General/MapManager.cs
index 1069f7da..fcb9b594 100644
--- a/Source/General/MapManager.cs
+++ b/Source/General/MapManager.cs
@@ -76,6 +76,8 @@ namespace CodeImp.DoomBuilder
private DataManager data;
private EditMode mode;
private EditMode newmode;
+ private Type prevmode;
+ private Type prevstablemode;
private D3DDevice graphics;
private Renderer2D renderer2d;
private Renderer3D renderer3d;
@@ -101,6 +103,8 @@ namespace CodeImp.DoomBuilder
public MapSet Map { get { return map; } }
public EditMode Mode { get { return mode; } }
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 bool IsChanged { get { return changed; } set { changed |= value; } }
public bool IsDisposed { get { return isdisposed; } }
@@ -862,7 +866,6 @@ namespace CodeImp.DoomBuilder
public void ChangeMode(EditMode nextmode)
{
EditMode oldmode = mode;
- newmode = nextmode;
cancelmodechange = false;
// Log info
@@ -871,6 +874,19 @@ namespace CodeImp.DoomBuilder
else
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
General.Plugins.ModeChanges(oldmode, newmode);
diff --git a/Source/IO/UniversalStreamWriter.cs b/Source/IO/UniversalStreamWriter.cs
index c25b09cd..6d0029aa 100644
--- a/Source/IO/UniversalStreamWriter.cs
+++ b/Source/IO/UniversalStreamWriter.cs
@@ -107,6 +107,17 @@ namespace CodeImp.DoomBuilder.IO
// This writes the structures to a stream
// writenamespace may be null to omit writing the namespace to the stream
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 vertices, ICollection linedefs,
+ ICollection sidedefs, ICollection sectors,
+ ICollection things, Stream stream, string writenamespace)
{
UniversalParser textmap = new UniversalParser();
@@ -118,24 +129,24 @@ namespace CodeImp.DoomBuilder.IO
Dictionary sectorids = new Dictionary();
// Index the elements in the data structures
- foreach(Vertex v in map.Vertices) vertexids.Add(v, vertexids.Count);
- foreach(Sidedef sd in map.Sidedefs) sidedefids.Add(sd, sidedefids.Count);
- foreach(Sector s in map.Sectors) sectorids.Add(s, sectorids.Count);
+ foreach(Vertex v in vertices) vertexids.Add(v, vertexids.Count);
+ foreach(Sidedef sd in sidedefs) sidedefids.Add(sd, sidedefids.Count);
+ foreach(Sector s in sectors) sectorids.Add(s, sectorids.Count);
// If we write the custom field types again, then forget
// all previous field types (this gets rid of unused field types)
if(remembercustomtypes) General.Map.Options.ForgetUniversalFieldTypes();
// Write the data structures to textmap
- WriteVertices(map.Vertices, textmap);
- WriteLinedefs(map.Linedefs, textmap, sidedefids, vertexids);
- WriteSidedefs(map.Sidedefs, textmap, sectorids);
- WriteSectors(map.Sectors, textmap);
- WriteThings(map.Things, textmap);
-
+ WriteVertices(vertices, textmap);
+ WriteLinedefs(linedefs, textmap, sidedefids, vertexids);
+ WriteSidedefs(sidedefs, textmap, sectorids);
+ WriteSectors(sectors, textmap);
+ WriteThings(things, textmap);
+
// Get the textmap as string
string textmapstr = textmap.OutputConfiguration();
-
+
// Write to stream
StreamWriter writer = new StreamWriter(stream, Encoding.ASCII);
writer.Write(textmapstr);
@@ -172,8 +183,19 @@ namespace CodeImp.DoomBuilder.IO
if(l.Tag != 0) coll.Add("id", l.Tag);
coll.Add("v1", vertexids[l.Start]);
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.Args[0] != 0) coll.Add("arg0", l.Args[0]);
if(l.Args[1] != 0) coll.Add("arg1", l.Args[1]);
@@ -199,6 +221,8 @@ namespace CodeImp.DoomBuilder.IO
// Go for all sidedefs
foreach(Sidedef s in sidedefs)
{
+ int sectorid = (s.Sector != null) ? sectorids[s.Sector] : -1;
+
// Make collection
UniversalCollection coll = new UniversalCollection();
if(s.OffsetX != 0) coll.Add("offsetx", s.OffsetX);
diff --git a/Source/Map/MapSet.cs b/Source/Map/MapSet.cs
index 0959a87a..93335067 100644
--- a/Source/Map/MapSet.cs
+++ b/Source/Map/MapSet.cs
@@ -441,18 +441,51 @@ namespace CodeImp.DoomBuilder.Map
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
#region ================== Marking
// This clears all marks
- public void ClearAllMarks()
+ public void ClearAllMarks(bool mark)
{
- ClearMarkedVertices(false);
- ClearMarkedThings(false);
- ClearMarkedLinedefs(false);
- ClearMarkedSectors(false);
- ClearMarkedSidedefs(false);
+ ClearMarkedVertices(mark);
+ ClearMarkedThings(mark);
+ ClearMarkedLinedefs(mark);
+ ClearMarkedSectors(mark);
+ ClearMarkedSidedefs(mark);
}
// This clears marked vertices
@@ -485,6 +518,46 @@ namespace CodeImp.DoomBuilder.Map
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
public List GetMarkedVertices(bool mark)
{
@@ -509,6 +582,14 @@ namespace CodeImp.DoomBuilder.Map
return list;
}
+ // Returns a collection of sidedefs that match a marked state
+ public List GetMarkedSidedefs(bool mark)
+ {
+ List list = new List(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
public List GetMarkedSectors(bool mark)
{
@@ -556,6 +637,17 @@ namespace CodeImp.DoomBuilder.Map
}
}
+ ///
+ /// This marks the sidedefs that make up the sectors with the matching mark
+ ///
+ public void MarkSidedefsFromSectors(bool matchmark, bool setmark)
+ {
+ foreach(Sidedef sd in sidedefs)
+ {
+ if(sd.Sector.Marked == matchmark) sd.Marked = setmark;
+ }
+ }
+
///
/// Returns a collection of vertices that match a marked state on the linedefs
///
@@ -620,6 +712,49 @@ namespace CodeImp.DoomBuilder.Map
}
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 verts = General.Map.Map.GetVerticesFromLinesMarks(mark);
+ foreach(Vertex v in verts) v.Marked = mark;
+
+ // Linedefs from vertices
+ ICollection 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
diff --git a/Source/Windows/MainForm.Designer.cs b/Source/Windows/MainForm.Designer.cs
index e524dd01..33f01f98 100644
--- a/Source/Windows/MainForm.Designer.cs
+++ b/Source/Windows/MainForm.Designer.cs
@@ -43,6 +43,7 @@ namespace CodeImp.DoomBuilder.Windows
System.Windows.Forms.ToolStripSeparator toolStripMenuItem4;
System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
+ System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.itemeditmodesseperator = 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.itemundo = 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.itemautomerge = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();
@@ -96,6 +101,7 @@ namespace CodeImp.DoomBuilder.Windows
this.statusbar = new System.Windows.Forms.StatusStrip();
this.statuslabel = 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.buttongrid = new System.Windows.Forms.ToolStripDropDownButton();
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.warningtimer = 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();
toolStripMenuItem2 = 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();
toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
+ toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
this.menumain.SuspendLayout();
this.toolbar.SuspendLayout();
this.statusbar.SuspendLayout();
@@ -230,6 +233,12 @@ namespace CodeImp.DoomBuilder.Windows
toolStripSeparator7.Name = "toolStripSeparator7";
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
//
this.itemeditmodesseperator.Name = "itemeditmodesseperator";
@@ -401,6 +410,38 @@ namespace CodeImp.DoomBuilder.Windows
this.itemredo.Text = "Redo";
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
//
this.itemsnaptogrid.Checked = true;
@@ -732,6 +773,8 @@ namespace CodeImp.DoomBuilder.Windows
this.statusbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.statuslabel,
this.warninglabel,
+ this.configlabel,
+ toolStripSeparator12,
this.gridlabel,
this.buttongrid,
toolStripSeparator1,
@@ -753,7 +796,7 @@ namespace CodeImp.DoomBuilder.Windows
this.statuslabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.statuslabel.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
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.Text = "Initializing user interface...";
this.statuslabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
@@ -770,12 +813,22 @@ namespace CodeImp.DoomBuilder.Windows
this.warninglabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
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
//
this.gridlabel.AutoSize = false;
this.gridlabel.AutoToolTip = true;
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.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
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);
//
- // 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
//
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 itemcopy;
private System.Windows.Forms.ToolStripMenuItem itempaste;
+ private System.Windows.Forms.ToolStripStatusLabel configlabel;
}
}
\ No newline at end of file
diff --git a/Source/Windows/MainForm.cs b/Source/Windows/MainForm.cs
index 439e4dc1..84454740 100644
--- a/Source/Windows/MainForm.cs
+++ b/Source/Windows/MainForm.cs
@@ -379,6 +379,7 @@ namespace CodeImp.DoomBuilder.Windows
buttonzoom.Enabled = true;
gridlabel.Enabled = true;
buttongrid.Enabled = true;
+ configlabel.Text = General.Map.Config.Name;
}
else
{
@@ -392,6 +393,7 @@ namespace CodeImp.DoomBuilder.Windows
buttonzoom.Enabled = false;
gridlabel.Enabled = false;
buttongrid.Enabled = false;
+ configlabel.Text = "";
}
}
diff --git a/Source/Windows/MainForm.resx b/Source/Windows/MainForm.resx
index 7d6e8c57..b0de6af5 100644
--- a/Source/Windows/MainForm.resx
+++ b/Source/Windows/MainForm.resx
@@ -159,6 +159,9 @@
False
+
+ False
+
17, 17