mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 05:41:45 +00:00
lots of stuff (including half decent copy/paste)
This commit is contained in:
parent
fccba768f0
commit
b1ccdbbc7f
29 changed files with 1692 additions and 1325 deletions
|
@ -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)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ClassicModes\BaseClassicMode.cs" />
|
||||
<Compile Include="ClassicModes\BrightnessMode.cs" />
|
||||
<Compile Include="ClassicModes\EditSelectionMode.cs" />
|
||||
<Compile Include="ClassicModes\CurveLinedefsMode.cs" />
|
||||
|
|
107
Source/BuilderModes/ClassicModes/BaseClassicMode.cs
Normal file
107
Source/BuilderModes/ClassicModes/BaseClassicMode.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.Actions;
|
||||
using CodeImp.DoomBuilder.Types;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.BuilderModes
|
||||
{
|
||||
public abstract class BaseClassicMode : ClassicMode
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public BaseClassicMode()
|
||||
{
|
||||
// Initialize
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Disposer
|
||||
public override void Dispose()
|
||||
{
|
||||
// Not already disposed?
|
||||
if(!isdisposed)
|
||||
{
|
||||
// Clean up
|
||||
|
||||
// Done
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This occurs when the user presses Copy. All selected geometry must be marked for copying!
|
||||
public override bool OnCopyBegin()
|
||||
{
|
||||
General.Map.Map.MarkAllSelectedGeometry(true);
|
||||
|
||||
// Return true when anything is selected so that the copy continues
|
||||
// We only have to check vertices for the geometry, because without selected
|
||||
// vertices, no complete structure can exist.
|
||||
return (General.Map.Map.GetMarkedVertices(true).Count > 0) ||
|
||||
(General.Map.Map.GetMarkedThings(true).Count > 0);
|
||||
}
|
||||
|
||||
// This is called when something is pasted.
|
||||
public override void OnPasteEnd()
|
||||
{
|
||||
General.Map.Map.ClearAllSelected();
|
||||
General.Map.Map.SelectMarkedGeometry(true, true);
|
||||
|
||||
// Switch to EditSelectionMode
|
||||
General.Map.ChangeMode("EditSelectionMode");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -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<Linedef> selectedlines;
|
||||
private ICollection<Linedef> 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<Vector2D> GenerateCurve(Linedef line)
|
||||
{
|
||||
// Fetch settings from window
|
||||
int vertices = BuilderPlug.Me.CurveLinedefsForm.Vertices;
|
||||
float distance = BuilderPlug.Me.CurveLinedefsForm.Distance;
|
||||
float angle = BuilderPlug.Me.CurveLinedefsForm.Angle;
|
||||
bool fixedcurve = BuilderPlug.Me.CurveLinedefsForm.FixedCurve;
|
||||
bool backwards = BuilderPlug.Me.CurveLinedefsForm.Backwards;
|
||||
|
||||
// Make list
|
||||
List<Vector2D> points = new List<Vector2D>(vertices);
|
||||
|
||||
//Added by Anders Åstrand 2008-05-18
|
||||
//The formulas used are taken from http://mathworld.wolfram.com/CircularSegment.html
|
||||
//c and theta are known (length of line and angle parameter). d, R and h are
|
||||
//calculated from those two
|
||||
//If the curve is not supposed to be a circular segment it's simply deformed to fit
|
||||
//the value set for distance.
|
||||
|
||||
//The vertices are generated to be evenly distributed (by angle) along the curve
|
||||
//and lastly they are rotated and moved to fit with the original line
|
||||
|
||||
//calculate some identities of a circle segment (refer to the graph in the url above)
|
||||
double c = line.Length;
|
||||
double theta = angle;
|
||||
|
||||
double d = (c / Math.Tan(theta / 2)) / 2;
|
||||
double R = d / Math.Cos(theta / 2);
|
||||
double h = R - d;
|
||||
|
||||
double yDeform = fixedcurve ? 1 : distance / h;
|
||||
if(backwards)
|
||||
yDeform = -yDeform;
|
||||
|
||||
double a, x, y;
|
||||
Vector2D vertex;
|
||||
|
||||
for(int v = 1; v <= vertices; v++)
|
||||
{
|
||||
//calculate the angle for this vertex
|
||||
//the curve starts at PI/2 - theta/2 and is segmented into vertices+1 segments
|
||||
//this assumes the line is horisontal and on y = 0, the point is rotated and moved later
|
||||
|
||||
a = (Math.PI - theta) / 2 + v * (theta / (vertices + 1));
|
||||
|
||||
//calculate the coordinates of the point, and distort the y coordinate
|
||||
//using the deform factor calculated above
|
||||
x = Math.Cos(a) * R;
|
||||
y = (Math.Sin(a) * R - d) * yDeform;
|
||||
|
||||
//rotate and transform to fit original line
|
||||
vertex = new Vector2D((float)x, (float)y).GetRotated(line.Angle + Angle2D.PIHALF);
|
||||
vertex = vertex.GetTransformed(line.GetCenterPoint().x, line.GetCenterPoint().y, 1, 1);
|
||||
|
||||
points.Add(vertex);
|
||||
}
|
||||
|
||||
|
||||
// Done
|
||||
return points;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
// Cancelled
|
||||
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<Vector2D> GenerateCurve(Linedef line)
|
||||
{
|
||||
// Fetch settings from window
|
||||
int vertices = BuilderPlug.Me.CurveLinedefsForm.Vertices;
|
||||
float distance = BuilderPlug.Me.CurveLinedefsForm.Distance;
|
||||
float angle = BuilderPlug.Me.CurveLinedefsForm.Angle;
|
||||
bool fixedcurve = BuilderPlug.Me.CurveLinedefsForm.FixedCurve;
|
||||
bool backwards = BuilderPlug.Me.CurveLinedefsForm.Backwards;
|
||||
|
||||
// Make list
|
||||
List<Vector2D> points = new List<Vector2D>(vertices);
|
||||
|
||||
//Added by Anders Åstrand 2008-05-18
|
||||
//The formulas used are taken from http://mathworld.wolfram.com/CircularSegment.html
|
||||
//c and theta are known (length of line and angle parameter). d, R and h are
|
||||
//calculated from those two
|
||||
//If the curve is not supposed to be a circular segment it's simply deformed to fit
|
||||
//the value set for distance.
|
||||
|
||||
//The vertices are generated to be evenly distributed (by angle) along the curve
|
||||
//and lastly they are rotated and moved to fit with the original line
|
||||
|
||||
//calculate some identities of a circle segment (refer to the graph in the url above)
|
||||
double c = line.Length;
|
||||
double theta = angle;
|
||||
|
||||
double d = (c / Math.Tan(theta / 2)) / 2;
|
||||
double R = d / Math.Cos(theta / 2);
|
||||
double h = R - d;
|
||||
|
||||
double yDeform = fixedcurve ? 1 : distance / h;
|
||||
if (backwards)
|
||||
yDeform = -yDeform;
|
||||
|
||||
double a, x, y;
|
||||
Vector2D vertex;
|
||||
|
||||
for (int v = 1; v <= vertices; v++)
|
||||
{
|
||||
//calculate the angle for this vertex
|
||||
//the curve starts at PI/2 - theta/2 and is segmented into vertices+1 segments
|
||||
//this assumes the line is horisontal and on y = 0, the point is rotated and moved later
|
||||
|
||||
a = (Math.PI - theta)/2 + v * (theta / (vertices + 1));
|
||||
|
||||
//calculate the coordinates of the point, and distort the y coordinate
|
||||
//using the deform factor calculated above
|
||||
x = Math.Cos(a) * R;
|
||||
y = (Math.Sin(a) * R - d) * yDeform;
|
||||
|
||||
//rotate and transform to fit original line
|
||||
vertex = new Vector2D((float)x, (float)y).GetRotated(line.Angle + Angle2D.PIHALF);
|
||||
vertex = vertex.GetTransformed(line.GetCenterPoint().x, line.GetCenterPoint().y, 1, 1);
|
||||
|
||||
points.Add(vertex);
|
||||
}
|
||||
|
||||
|
||||
// Done
|
||||
return points;
|
||||
General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
|
||||
}
|
||||
|
||||
// Redrawing display
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Marked = true;
|
||||
|
|
|
@ -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<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Marked = true;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<DrawnVertex> points;
|
||||
private List<LineLengthLabel> 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<DrawnVertex>();
|
||||
labels = new List<LineLengthLabel>();
|
||||
|
||||
// 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<Vector2D> coords = nl.GetGridIntersections();
|
||||
|
||||
// Find nearest grid intersection
|
||||
float found_distance = float.MaxValue;
|
||||
Vector2D found_coord = new Vector2D();
|
||||
foreach(Vector2D v in coords)
|
||||
{
|
||||
Vector2D delta = mousemappos - v;
|
||||
if(delta.GetLengthSq() < found_distance)
|
||||
{
|
||||
found_distance = delta.GetLengthSq();
|
||||
found_coord = v;
|
||||
}
|
||||
}
|
||||
|
||||
// Align to the closest grid intersection
|
||||
p.pos = found_coord;
|
||||
p.stitch = true;
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Aligned to line
|
||||
p.pos = nl.NearestOnLine(mousemappos);
|
||||
p.stitch = true;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Snap to grid?
|
||||
if(snaptogrid)
|
||||
{
|
||||
// Aligned to grid
|
||||
p.pos = General.Map.Grid.SnappedToGrid(mousemappos);
|
||||
p.stitch = snaptonearest;
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal position
|
||||
p.pos = mousemappos;
|
||||
p.stitch = snaptonearest;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
// This draws a point at a specific location
|
||||
public void DrawPointAt(Vector2D pos, bool stitch)
|
||||
{
|
||||
DrawnVertex newpoint = new DrawnVertex();
|
||||
newpoint.pos = pos;
|
||||
newpoint.stitch = stitch;
|
||||
points.Add(newpoint);
|
||||
labels.Add(new LineLengthLabel());
|
||||
labels[labels.Count - 1].Start = newpoint.pos;
|
||||
if(labels.Count > 1) labels[labels.Count - 2].End = newpoint.pos;
|
||||
Update();
|
||||
|
||||
// Check if point stitches with the first
|
||||
if((points.Count > 1) && (points[points.Count - 1].stitch))
|
||||
{
|
||||
Vector2D p1 = points[0].pos;
|
||||
Vector2D p2 = points[points.Count - 1].pos;
|
||||
Vector2D delta = p1 - p2;
|
||||
if((Math.Abs(delta.x) <= 0.001f) && (Math.Abs(delta.y) <= 0.001f))
|
||||
{
|
||||
// Finish drawing
|
||||
FinishDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
// Engaging
|
||||
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<Vector2D> coords = nl.GetGridIntersections();
|
||||
|
||||
// Find nearest grid intersection
|
||||
float found_distance = float.MaxValue;
|
||||
Vector2D found_coord = new Vector2D();
|
||||
foreach(Vector2D v in coords)
|
||||
{
|
||||
Vector2D delta = mousemappos - v;
|
||||
if(delta.GetLengthSq() < found_distance)
|
||||
{
|
||||
found_distance = delta.GetLengthSq();
|
||||
found_coord = v;
|
||||
}
|
||||
}
|
||||
|
||||
// Align to the closest grid intersection
|
||||
p.pos = found_coord;
|
||||
p.stitch = true;
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Aligned to line
|
||||
p.pos = nl.NearestOnLine(mousemappos);
|
||||
p.stitch = true;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Snap to grid?
|
||||
if(snaptogrid)
|
||||
{
|
||||
// Aligned to grid
|
||||
p.pos = General.Map.Grid.SnappedToGrid(mousemappos);
|
||||
p.stitch = snaptonearest;
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal position
|
||||
p.pos = mousemappos;
|
||||
p.stitch = snaptonearest;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse moving
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Marked = true;
|
||||
selectedvertices = General.Map.Map.GetMarkedVertices(true);
|
||||
selectedthings = General.Map.Map.GetMarkedThings(true);
|
||||
unselectedvertices = General.Map.Map.GetMarkedVertices(false);
|
||||
|
||||
// Make sure everything is selected so that it turns up red
|
||||
foreach(Vertex v in selectedvertices) v.Selected = true;
|
||||
ICollection<Linedef> markedlines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
|
||||
foreach(Linedef l in markedlines) l.Selected = true;
|
||||
unselectedlines = General.Map.Map.LinedefsFromMarkedVertices(true, false, false);
|
||||
|
||||
// Array to keep original coordinates
|
||||
vertexpos = new List<Vector2D>(selectedvertices.Count);
|
||||
thingpos = new List<Vector2D>(selectedthings.Count);
|
||||
|
||||
// A selection must be made!
|
||||
if((selectedvertices.Count > 0) || (selectedthings.Count > 0))
|
||||
{
|
||||
// Initialize offset and size
|
||||
offset.x = float.MaxValue;
|
||||
offset.y = float.MaxValue;
|
||||
Vector2D right;
|
||||
right.x = float.MinValue;
|
||||
right.y = float.MinValue;
|
||||
|
||||
foreach(Vertex v in selectedvertices)
|
||||
{
|
||||
// Find left-top and right-bottom
|
||||
if(v.Position.x < offset.x) offset.x = v.Position.x;
|
||||
if(v.Position.y < offset.y) offset.y = v.Position.y;
|
||||
if(v.Position.x > right.x) right.x = v.Position.x;
|
||||
if(v.Position.y > right.y) right.y = v.Position.y;
|
||||
|
||||
// Keep original coordinates
|
||||
vertexpos.Add(v.Position);
|
||||
}
|
||||
|
||||
foreach(Thing t in selectedthings)
|
||||
{
|
||||
// Find left-top and right-bottom
|
||||
if(t.Position.x < offset.x) offset.x = t.Position.x;
|
||||
if(t.Position.y < offset.y) offset.y = t.Position.y;
|
||||
if(t.Position.x > right.x) right.x = t.Position.x;
|
||||
if(t.Position.y > right.y) right.y = t.Position.y;
|
||||
|
||||
// Keep original coordinates
|
||||
thingpos.Add(t.Position);
|
||||
}
|
||||
|
||||
// Calculate size
|
||||
size = right - offset;
|
||||
|
||||
// If the width of a dimension is zero, add a little
|
||||
if(Math.Abs(size.x) < 1.0f)
|
||||
{
|
||||
size.x += ZERO_SIZE_ADDITION;
|
||||
offset.x -= ZERO_SIZE_ADDITION / 2;
|
||||
}
|
||||
|
||||
if(Math.Abs(size.y) < 1.0f)
|
||||
{
|
||||
size.y += ZERO_SIZE_ADDITION;
|
||||
offset.y -= ZERO_SIZE_ADDITION / 2;
|
||||
}
|
||||
|
||||
basesize = size;
|
||||
baseoffset = offset;
|
||||
|
||||
// Set presentation
|
||||
if(selectedthings.Count > 0)
|
||||
renderer.SetPresentation(Presentation.Things);
|
||||
else
|
||||
renderer.SetPresentation(Presentation.Standard);
|
||||
|
||||
// Update
|
||||
UpdateRectangleComponents();
|
||||
}
|
||||
else
|
||||
{
|
||||
General.Interface.DisplayWarning("Please make a selection first!");
|
||||
|
||||
// Cancel now
|
||||
General.Map.CancelMode();
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel mode
|
||||
public override void OnCancel()
|
||||
{
|
||||
base.OnCancel();
|
||||
|
||||
// Reset geometry in original position
|
||||
int index = 0;
|
||||
foreach(Vertex v in selectedvertices)
|
||||
v.Move(vertexpos[index++]);
|
||||
|
||||
index = 0;
|
||||
foreach(Thing t in selectedthings)
|
||||
t.Move(thingpos[index++]);
|
||||
|
||||
General.Map.Map.Update(true, true);
|
||||
|
||||
// Return to original mode
|
||||
Type mt = basemode.GetType();
|
||||
basemode = (EditMode)Activator.CreateInstance(mt);
|
||||
General.Map.ChangeMode(basemode);
|
||||
}
|
||||
|
||||
// When accepted
|
||||
public override void OnAccept()
|
||||
{
|
||||
base.OnAccept();
|
||||
|
||||
// Anything to do?
|
||||
if((selectedthings.Count > 0) || (selectedvertices.Count > 0))
|
||||
{
|
||||
Cursor.Current = Cursors.AppStarting;
|
||||
|
||||
// Reset geometry in original position
|
||||
int index = 0;
|
||||
foreach(Vertex v in selectedvertices)
|
||||
v.Move(vertexpos[index++]);
|
||||
|
||||
index = 0;
|
||||
foreach(Thing t in selectedthings)
|
||||
t.Move(thingpos[index++]);
|
||||
|
||||
// Make undo
|
||||
General.Map.UndoRedo.CreateUndo("Edit selection", UndoGroup.None, 0);
|
||||
|
||||
// Move geometry to new position
|
||||
UpdateGeometry();
|
||||
General.Map.Map.Update(true, true);
|
||||
|
||||
// Stitch geometry
|
||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
||||
|
||||
// Snap to map format accuracy
|
||||
General.Map.Map.SnapAllToAccuracy();
|
||||
|
||||
// Update cached values
|
||||
General.Map.Map.Update();
|
||||
|
||||
// Done
|
||||
selectedvertices = new List<Vertex>();
|
||||
selectedthings = new List<Thing>();
|
||||
Cursor.Current = Cursors.Default;
|
||||
General.Map.IsChanged = true;
|
||||
}
|
||||
|
||||
if(!modealreadyswitching)
|
||||
{
|
||||
// Return to original mode
|
||||
Type mt = basemode.GetType();
|
||||
basemode = (EditMode)Activator.CreateInstance(mt);
|
||||
General.Map.ChangeMode(basemode);
|
||||
}
|
||||
}
|
||||
|
||||
// Mode disengages
|
||||
public override void OnDisengage()
|
||||
{
|
||||
base.OnDisengage();
|
||||
|
||||
// When not cancelled manually, we assume it is accepted
|
||||
if(!cancelled)
|
||||
{
|
||||
modealreadyswitching = true;
|
||||
this.OnAccept();
|
||||
}
|
||||
|
||||
// Hide highlight info
|
||||
General.Interface.HideInfo();
|
||||
General.Interface.SetCursor(Cursors.Default);
|
||||
}
|
||||
|
||||
// This redraws the display
|
||||
public override void OnRedrawDisplay()
|
||||
{
|
||||
UpdateRectangleComponents();
|
||||
|
||||
// Render lines
|
||||
if(renderer.StartPlotter(true))
|
||||
{
|
||||
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
||||
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
||||
if(highlighted != null) renderer.PlotVertex(highlighted, ColorCollection.HIGHLIGHT);
|
||||
renderer.Finish();
|
||||
}
|
||||
|
||||
// Render things
|
||||
if(renderer.StartThings(true))
|
||||
{
|
||||
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
|
||||
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
|
||||
renderer.Finish();
|
||||
}
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
// Rectangle
|
||||
PixelColor rectcolor = General.Colors.Highlight.WithAlpha(RECTANGLE_ALPHA);
|
||||
renderer.RenderGeometry(cornerverts, null, true);
|
||||
renderer.RenderLine(corners[0], corners[1], 4, rectcolor, true);
|
||||
renderer.RenderLine(corners[1], corners[2], 4, rectcolor, true);
|
||||
renderer.RenderLine(corners[2], corners[3], 4, rectcolor, true);
|
||||
renderer.RenderLine(corners[3], corners[0], 4, rectcolor, true);
|
||||
|
||||
// Extension line
|
||||
if(extensionline.GetLengthSq() > 0.0f)
|
||||
renderer.RenderLine(extensionline.v1, extensionline.v2, 1, General.Colors.Indication.WithAlpha(EXTENSION_LINE_ALPHA), true);
|
||||
|
||||
// Grips
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
renderer.RenderRectangleFilled(resizegrips[i], General.Colors.Background, true);
|
||||
renderer.RenderRectangle(resizegrips[i], 2, General.Colors.Highlight, true);
|
||||
renderer.RenderRectangleFilled(rotategrips[i], General.Colors.Background, true);
|
||||
renderer.RenderRectangle(rotategrips[i], 2, General.Colors.Indication, true);
|
||||
}
|
||||
|
||||
renderer.Finish();
|
||||
}
|
||||
|
||||
renderer.Present();
|
||||
}
|
||||
|
||||
// Mouse moves
|
||||
public override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
// Mouse leaves the display
|
||||
public override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
|
||||
// Reset cursor
|
||||
General.Interface.SetCursor(Cursors.Default);
|
||||
}
|
||||
|
||||
// When edit button is pressed
|
||||
protected override void OnEdit()
|
||||
{
|
||||
base.OnEdit();
|
||||
OnSelect();
|
||||
}
|
||||
|
||||
// When edit button is released
|
||||
protected override void OnEndEdit()
|
||||
{
|
||||
base.OnEndEdit();
|
||||
OnEndSelect();
|
||||
}
|
||||
|
||||
// When select button is pressed
|
||||
protected override void OnSelect()
|
||||
{
|
||||
base.OnSelect();
|
||||
|
||||
// Used in many cases:
|
||||
Vector2D center = offset + size * 0.5f;
|
||||
Vector2D delta;
|
||||
|
||||
// Check what grip the mouse is over
|
||||
switch(CheckMouseGrip())
|
||||
{
|
||||
// Drag main rectangle
|
||||
case Grip.Main:
|
||||
|
||||
// Find the original position of the highlighted vertex
|
||||
if(highlighted != null)
|
||||
{
|
||||
int index = 0;
|
||||
foreach(Vertex v in selectedvertices)
|
||||
{
|
||||
if(v == highlighted) highlightedpos = vertexpos[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
dragoffset = mousemappos - offset;
|
||||
mode = ModifyMode.Dragging;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeN:
|
||||
|
||||
// The resize vector is a unit vector in the direction of the resize.
|
||||
// We multiply this with the sign of the current size, because the
|
||||
// corners may be reversed when the selection is flipped.
|
||||
resizevector = corners[1] - corners[2];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
|
||||
|
||||
// The edgevector is a vector with length and direction of the edge perpendicular to the resizevector
|
||||
edgevector = corners[1] - corners[0];
|
||||
|
||||
// Make the resize axis. This is a line with the length and direction
|
||||
// of basesize used to calculate the resize percentage.
|
||||
resizeaxis = new Line2D(corners[2], corners[2] + resizevector * basesize.y);
|
||||
|
||||
// Original axis filter
|
||||
resizefilter = new Vector2D(0.0f, 1.0f);
|
||||
|
||||
// This is the corner that must stay in the same position
|
||||
stickcorner = 2;
|
||||
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeE:
|
||||
// See description above
|
||||
resizevector = corners[1] - corners[0];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
|
||||
edgevector = corners[1] - corners[2];
|
||||
resizeaxis = new Line2D(corners[0], corners[0] + resizevector * basesize.x);
|
||||
resizefilter = new Vector2D(1.0f, 0.0f);
|
||||
stickcorner = 0;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeS:
|
||||
// See description above
|
||||
resizevector = corners[2] - corners[1];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
|
||||
edgevector = corners[2] - corners[3];
|
||||
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.y);
|
||||
resizefilter = new Vector2D(0.0f, 1.0f);
|
||||
stickcorner = 0;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeW:
|
||||
// See description above
|
||||
resizevector = corners[0] - corners[1];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
|
||||
edgevector = corners[0] - corners[3];
|
||||
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.x);
|
||||
resizefilter = new Vector2D(1.0f, 0.0f);
|
||||
stickcorner = 1;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateLB:
|
||||
delta = corners[3] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateLT:
|
||||
delta = corners[0] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateRB:
|
||||
delta = corners[2] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateRT:
|
||||
delta = corners[1] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Outside the selection?
|
||||
default:
|
||||
// Accept and be done with it
|
||||
General.Map.AcceptMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When selected button is released
|
||||
protected override void OnEndSelect()
|
||||
{
|
||||
base.OnEndSelect();
|
||||
|
||||
// Remove extension line
|
||||
extensionline = new Line2D();
|
||||
|
||||
// No modifying mode
|
||||
mode = ModifyMode.None;
|
||||
|
||||
// Redraw
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// When a key is released
|
||||
public override void OnKeyUp(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyUp(e);
|
||||
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
|
||||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
|
||||
}
|
||||
|
||||
// When a key is pressed
|
||||
public override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
|
||||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#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<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(true);
|
||||
foreach(Vertex v in verts) v.Marked = true;
|
||||
selectedvertices = General.Map.Map.GetMarkedVertices(true);
|
||||
selectedthings = General.Map.Map.GetMarkedThings(true);
|
||||
unselectedvertices = General.Map.Map.GetMarkedVertices(false);
|
||||
|
||||
// Make sure everything is selected so that it turns up red
|
||||
foreach(Vertex v in selectedvertices) v.Selected = true;
|
||||
ICollection<Linedef> markedlines = General.Map.Map.LinedefsFromMarkedVertices(false, true, false);
|
||||
foreach(Linedef l in markedlines) l.Selected = true;
|
||||
unselectedlines = General.Map.Map.LinedefsFromMarkedVertices(true, false, false);
|
||||
|
||||
// Array to keep original coordinates
|
||||
vertexpos = new List<Vector2D>(selectedvertices.Count);
|
||||
thingpos = new List<Vector2D>(selectedthings.Count);
|
||||
|
||||
// A selection must be made!
|
||||
if((selectedvertices.Count > 0) || (selectedthings.Count > 0))
|
||||
{
|
||||
// Initialize offset and size
|
||||
offset.x = float.MaxValue;
|
||||
offset.y = float.MaxValue;
|
||||
Vector2D right;
|
||||
right.x = float.MinValue;
|
||||
right.y = float.MinValue;
|
||||
|
||||
foreach(Vertex v in selectedvertices)
|
||||
{
|
||||
// Find left-top and right-bottom
|
||||
if(v.Position.x < offset.x) offset.x = v.Position.x;
|
||||
if(v.Position.y < offset.y) offset.y = v.Position.y;
|
||||
if(v.Position.x > right.x) right.x = v.Position.x;
|
||||
if(v.Position.y > right.y) right.y = v.Position.y;
|
||||
|
||||
// Keep original coordinates
|
||||
vertexpos.Add(v.Position);
|
||||
}
|
||||
|
||||
foreach(Thing t in selectedthings)
|
||||
{
|
||||
// Find left-top and right-bottom
|
||||
if(t.Position.x < offset.x) offset.x = t.Position.x;
|
||||
if(t.Position.y < offset.y) offset.y = t.Position.y;
|
||||
if(t.Position.x > right.x) right.x = t.Position.x;
|
||||
if(t.Position.y > right.y) right.y = t.Position.y;
|
||||
|
||||
// Keep original coordinates
|
||||
thingpos.Add(t.Position);
|
||||
}
|
||||
|
||||
// Calculate size
|
||||
size = right - offset;
|
||||
|
||||
// If the width of a dimension is zero, add a little
|
||||
if(Math.Abs(size.x) < 1.0f)
|
||||
{
|
||||
size.x += ZERO_SIZE_ADDITION;
|
||||
offset.x -= ZERO_SIZE_ADDITION / 2;
|
||||
}
|
||||
|
||||
if(Math.Abs(size.y) < 1.0f)
|
||||
{
|
||||
size.y += ZERO_SIZE_ADDITION;
|
||||
offset.y -= ZERO_SIZE_ADDITION / 2;
|
||||
}
|
||||
|
||||
basesize = size;
|
||||
baseoffset = offset;
|
||||
|
||||
// Set presentation
|
||||
if(selectedthings.Count > 0)
|
||||
renderer.SetPresentation(Presentation.Things);
|
||||
else
|
||||
renderer.SetPresentation(Presentation.Standard);
|
||||
|
||||
// Update
|
||||
UpdateRectangleComponents();
|
||||
}
|
||||
else
|
||||
{
|
||||
General.Interface.DisplayWarning("Please make a selection first!");
|
||||
|
||||
// Cancel now
|
||||
General.Map.CancelMode();
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel mode
|
||||
public override void OnCancel()
|
||||
{
|
||||
base.OnCancel();
|
||||
|
||||
// Reset geometry in original position
|
||||
int index = 0;
|
||||
foreach(Vertex v in selectedvertices)
|
||||
v.Move(vertexpos[index++]);
|
||||
|
||||
index = 0;
|
||||
foreach(Thing t in selectedthings)
|
||||
t.Move(thingpos[index++]);
|
||||
|
||||
General.Map.Map.Update(true, true);
|
||||
|
||||
// Return to previous stable mode
|
||||
General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
|
||||
}
|
||||
|
||||
// When accepted
|
||||
public override void OnAccept()
|
||||
{
|
||||
base.OnAccept();
|
||||
|
||||
// Anything to do?
|
||||
if((selectedthings.Count > 0) || (selectedvertices.Count > 0))
|
||||
{
|
||||
Cursor.Current = Cursors.AppStarting;
|
||||
|
||||
// Reset geometry in original position
|
||||
int index = 0;
|
||||
foreach(Vertex v in selectedvertices)
|
||||
v.Move(vertexpos[index++]);
|
||||
|
||||
index = 0;
|
||||
foreach(Thing t in selectedthings)
|
||||
t.Move(thingpos[index++]);
|
||||
|
||||
// Make undo
|
||||
General.Map.UndoRedo.CreateUndo("Edit selection", UndoGroup.None, 0);
|
||||
|
||||
// Move geometry to new position
|
||||
UpdateGeometry();
|
||||
General.Map.Map.Update(true, true);
|
||||
|
||||
// Stitch geometry
|
||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
||||
|
||||
// Snap to map format accuracy
|
||||
General.Map.Map.SnapAllToAccuracy();
|
||||
|
||||
// Update cached values
|
||||
General.Map.Map.Update();
|
||||
|
||||
// Done
|
||||
selectedvertices = new List<Vertex>();
|
||||
selectedthings = new List<Thing>();
|
||||
Cursor.Current = Cursors.Default;
|
||||
General.Map.IsChanged = true;
|
||||
}
|
||||
|
||||
if(!modealreadyswitching)
|
||||
{
|
||||
// Return to previous stable mode
|
||||
General.Map.ChangeMode(General.Map.PreviousStableMode.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// Mode disengages
|
||||
public override void OnDisengage()
|
||||
{
|
||||
base.OnDisengage();
|
||||
|
||||
// When not cancelled manually, we assume it is accepted
|
||||
if(!cancelled)
|
||||
{
|
||||
modealreadyswitching = true;
|
||||
this.OnAccept();
|
||||
}
|
||||
|
||||
// Hide highlight info
|
||||
General.Interface.HideInfo();
|
||||
General.Interface.SetCursor(Cursors.Default);
|
||||
}
|
||||
|
||||
// This redraws the display
|
||||
public override void OnRedrawDisplay()
|
||||
{
|
||||
UpdateRectangleComponents();
|
||||
|
||||
// Render lines
|
||||
if(renderer.StartPlotter(true))
|
||||
{
|
||||
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
||||
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
||||
if(highlighted != null) renderer.PlotVertex(highlighted, ColorCollection.HIGHLIGHT);
|
||||
renderer.Finish();
|
||||
}
|
||||
|
||||
// Render things
|
||||
if(renderer.StartThings(true))
|
||||
{
|
||||
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, Presentation.THINGS_HIDDEN_ALPHA);
|
||||
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, 1.0f);
|
||||
renderer.Finish();
|
||||
}
|
||||
|
||||
// Render selection
|
||||
if(renderer.StartOverlay(true))
|
||||
{
|
||||
// Rectangle
|
||||
PixelColor rectcolor = General.Colors.Highlight.WithAlpha(RECTANGLE_ALPHA);
|
||||
renderer.RenderGeometry(cornerverts, null, true);
|
||||
renderer.RenderLine(corners[0], corners[1], 4, rectcolor, true);
|
||||
renderer.RenderLine(corners[1], corners[2], 4, rectcolor, true);
|
||||
renderer.RenderLine(corners[2], corners[3], 4, rectcolor, true);
|
||||
renderer.RenderLine(corners[3], corners[0], 4, rectcolor, true);
|
||||
|
||||
// Extension line
|
||||
if(extensionline.GetLengthSq() > 0.0f)
|
||||
renderer.RenderLine(extensionline.v1, extensionline.v2, 1, General.Colors.Indication.WithAlpha(EXTENSION_LINE_ALPHA), true);
|
||||
|
||||
// Grips
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
renderer.RenderRectangleFilled(resizegrips[i], General.Colors.Background, true);
|
||||
renderer.RenderRectangle(resizegrips[i], 2, General.Colors.Highlight, true);
|
||||
renderer.RenderRectangleFilled(rotategrips[i], General.Colors.Background, true);
|
||||
renderer.RenderRectangle(rotategrips[i], 2, General.Colors.Indication, true);
|
||||
}
|
||||
|
||||
renderer.Finish();
|
||||
}
|
||||
|
||||
renderer.Present();
|
||||
}
|
||||
|
||||
// Mouse moves
|
||||
public override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
// Mouse leaves the display
|
||||
public override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
base.OnMouseLeave(e);
|
||||
|
||||
// Reset cursor
|
||||
General.Interface.SetCursor(Cursors.Default);
|
||||
}
|
||||
|
||||
// When edit button is pressed
|
||||
protected override void OnEdit()
|
||||
{
|
||||
base.OnEdit();
|
||||
OnSelect();
|
||||
}
|
||||
|
||||
// When edit button is released
|
||||
protected override void OnEndEdit()
|
||||
{
|
||||
base.OnEndEdit();
|
||||
OnEndSelect();
|
||||
}
|
||||
|
||||
// When select button is pressed
|
||||
protected override void OnSelect()
|
||||
{
|
||||
base.OnSelect();
|
||||
|
||||
// Used in many cases:
|
||||
Vector2D center = offset + size * 0.5f;
|
||||
Vector2D delta;
|
||||
|
||||
// Check what grip the mouse is over
|
||||
switch(CheckMouseGrip())
|
||||
{
|
||||
// Drag main rectangle
|
||||
case Grip.Main:
|
||||
|
||||
// Find the original position of the highlighted vertex
|
||||
if(highlighted != null)
|
||||
{
|
||||
int index = 0;
|
||||
foreach(Vertex v in selectedvertices)
|
||||
{
|
||||
if(v == highlighted) highlightedpos = vertexpos[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
dragoffset = mousemappos - offset;
|
||||
mode = ModifyMode.Dragging;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeN:
|
||||
|
||||
// The resize vector is a unit vector in the direction of the resize.
|
||||
// We multiply this with the sign of the current size, because the
|
||||
// corners may be reversed when the selection is flipped.
|
||||
resizevector = corners[1] - corners[2];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
|
||||
|
||||
// The edgevector is a vector with length and direction of the edge perpendicular to the resizevector
|
||||
edgevector = corners[1] - corners[0];
|
||||
|
||||
// Make the resize axis. This is a line with the length and direction
|
||||
// of basesize used to calculate the resize percentage.
|
||||
resizeaxis = new Line2D(corners[2], corners[2] + resizevector * basesize.y);
|
||||
|
||||
// Original axis filter
|
||||
resizefilter = new Vector2D(0.0f, 1.0f);
|
||||
|
||||
// This is the corner that must stay in the same position
|
||||
stickcorner = 2;
|
||||
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeE:
|
||||
// See description above
|
||||
resizevector = corners[1] - corners[0];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
|
||||
edgevector = corners[1] - corners[2];
|
||||
resizeaxis = new Line2D(corners[0], corners[0] + resizevector * basesize.x);
|
||||
resizefilter = new Vector2D(1.0f, 0.0f);
|
||||
stickcorner = 0;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeS:
|
||||
// See description above
|
||||
resizevector = corners[2] - corners[1];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.y);
|
||||
edgevector = corners[2] - corners[3];
|
||||
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.y);
|
||||
resizefilter = new Vector2D(0.0f, 1.0f);
|
||||
stickcorner = 0;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Resize
|
||||
case Grip.SizeW:
|
||||
// See description above
|
||||
resizevector = corners[0] - corners[1];
|
||||
resizevector = resizevector.GetNormal() * Math.Sign(size.x);
|
||||
edgevector = corners[0] - corners[3];
|
||||
resizeaxis = new Line2D(corners[1], corners[1] + resizevector * basesize.x);
|
||||
resizefilter = new Vector2D(1.0f, 0.0f);
|
||||
stickcorner = 1;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Resizing;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateLB:
|
||||
delta = corners[3] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateLT:
|
||||
delta = corners[0] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateRB:
|
||||
delta = corners[2] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Rotate
|
||||
case Grip.RotateRT:
|
||||
delta = corners[1] - center;
|
||||
rotategripangle = delta.GetAngle() - rotation;
|
||||
Highlight(null);
|
||||
mode = ModifyMode.Rotating;
|
||||
break;
|
||||
|
||||
// Outside the selection?
|
||||
default:
|
||||
// Accept and be done with it
|
||||
General.Map.AcceptMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When selected button is released
|
||||
protected override void OnEndSelect()
|
||||
{
|
||||
base.OnEndSelect();
|
||||
|
||||
// Remove extension line
|
||||
extensionline = new Line2D();
|
||||
|
||||
// No modifying mode
|
||||
mode = ModifyMode.None;
|
||||
|
||||
// Redraw
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
// When a key is released
|
||||
public override void OnKeyUp(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyUp(e);
|
||||
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
|
||||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
|
||||
}
|
||||
|
||||
// When a key is pressed
|
||||
public override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
if((snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) ||
|
||||
(snaptonearest != (General.Interface.CtrlState ^ General.Interface.AutoMerge))) Update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Actions
|
||||
|
||||
// This clears the selection
|
||||
[BeginAction("clearselection", BaseAction = true)]
|
||||
public void ClearSelection()
|
||||
{
|
||||
// Accept changes
|
||||
General.Map.Map.ClearAllSelected();
|
||||
General.Map.AcceptMode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Linedef> 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
|
||||
|
|
|
@ -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<Linedef>(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<Linedef>(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()
|
||||
{
|
||||
|
|
|
@ -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<Linedef> selectedlines = General.Map.Map.GetSelectedLinedefs(true);
|
||||
foreach(Linedef ld in selectedlines)
|
||||
{
|
||||
// Front and back side?
|
||||
if((ld.Front != null) && (ld.Back != null))
|
||||
{
|
||||
// Both a selected sector, but not the same?
|
||||
if(ld.Front.Sector.Selected && ld.Back.Sector.Selected &&
|
||||
(ld.Front.Sector != ld.Back.Sector))
|
||||
{
|
||||
// Remove this line
|
||||
ld.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Redraw
|
||||
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<Linedef> 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<Linedef> selectedlines = General.Map.Map.GetSelectedLinedefs(true);
|
||||
foreach(Linedef ld in selectedlines)
|
||||
{
|
||||
// Front and back side?
|
||||
if((ld.Front != null) && (ld.Back != null))
|
||||
{
|
||||
// Both a selected sector, but not the same?
|
||||
if(ld.Front.Sector.Selected && ld.Back.Sector.Selected &&
|
||||
(ld.Front.Sector != ld.Back.Sector))
|
||||
{
|
||||
// Remove this line
|
||||
ld.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all selected sectors with the first
|
||||
for(int i = 1; i < orderedselection.Count; i++)
|
||||
orderedselection[i].Join(orderedselection[0]);
|
||||
}
|
||||
// Clear selection
|
||||
General.Map.Map.ClearAllSelected();
|
||||
|
||||
// Redraw
|
||||
General.Interface.RedrawDisplay();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Linedef> 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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<SkillInfo>();
|
||||
|
||||
// Read general settings
|
||||
configname = cfg.ReadSetting("game", "<unnamed game>");
|
||||
enginename = cfg.ReadSetting("engine", "");
|
||||
defaulttexturescale = cfg.ReadSetting("defaulttexturescale", 1f);
|
||||
defaultflatscale = cfg.ReadSetting("defaultflatscale", 1f);
|
||||
|
|
|
@ -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<Vertex> verts = General.Map.Map.GetMarkedVertices(true);
|
||||
ICollection<Sidedef> sides = General.Map.Map.GetMarkedSidedefs(true);
|
||||
ICollection<Sector> sectors = General.Map.Map.GetMarkedSectors(true);
|
||||
ICollection<Linedef> lines = General.Map.Map.GetMarkedLinedefs(true);
|
||||
ICollection<Thing> things = General.Map.Map.GetMarkedThings(true);
|
||||
|
||||
// Write data to stream
|
||||
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
|
||||
{
|
||||
|
|
|
@ -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) { }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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<Vertex> vertices, ICollection<Linedef> linedefs,
|
||||
ICollection<Sidedef> sidedefs, ICollection<Sector> sectors,
|
||||
ICollection<Thing> things, Stream stream, string writenamespace)
|
||||
{
|
||||
UniversalParser textmap = new UniversalParser();
|
||||
|
||||
|
@ -118,24 +129,24 @@ namespace CodeImp.DoomBuilder.IO
|
|||
Dictionary<Sector, int> sectorids = new Dictionary<Sector, int>();
|
||||
|
||||
// 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);
|
||||
|
|
|
@ -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<Vertex> 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<Sidedef> GetMarkedSidedefs(bool mark)
|
||||
{
|
||||
List<Sidedef> list = new List<Sidedef>(sidedefs.Count >> 1);
|
||||
foreach(Sidedef s in sidedefs) if(s.Marked == mark) list.Add(s);
|
||||
return list;
|
||||
}
|
||||
|
||||
// Returns a collection of sectors that match a marked state
|
||||
public List<Sector> GetMarkedSectors(bool mark)
|
||||
{
|
||||
|
@ -556,6 +637,17 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This marks the sidedefs that make up the sectors with the matching mark
|
||||
/// </summary>
|
||||
public void MarkSidedefsFromSectors(bool matchmark, bool setmark)
|
||||
{
|
||||
foreach(Sidedef sd in sidedefs)
|
||||
{
|
||||
if(sd.Sector.Marked == matchmark) sd.Marked = setmark;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of vertices that match a marked state on the linedefs
|
||||
/// </summary>
|
||||
|
@ -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<Vertex> verts = General.Map.Map.GetVerticesFromLinesMarks(mark);
|
||||
foreach(Vertex v in verts) v.Marked = mark;
|
||||
|
||||
// Linedefs from vertices
|
||||
ICollection<Linedef> lines = General.Map.Map.LinedefsFromMarkedVertices(!mark, mark, !mark);
|
||||
foreach(Linedef l in lines) l.Marked = mark;
|
||||
|
||||
// Mark sectors from linedefs (note: this must be the first to mark
|
||||
// sectors, because this clears the sector marks!)
|
||||
General.Map.Map.ClearMarkedSectors(mark);
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
{
|
||||
if(!l.Selected)
|
||||
{
|
||||
if(l.Front != null) l.Front.Sector.Marked = !mark;
|
||||
if(l.Back != null) l.Back.Sector.Marked = !mark;
|
||||
}
|
||||
}
|
||||
|
||||
// Direct sectors
|
||||
General.Map.Map.MarkSelectedSectors(true, mark);
|
||||
|
||||
// Direct things
|
||||
General.Map.Map.MarkSelectedThings(true, mark);
|
||||
|
||||
// Sidedefs from linedefs
|
||||
//General.Map.Map.MarkSidedefsFromLinedefs(true, mark);
|
||||
General.Map.Map.MarkSidedefsFromSectors(true, mark);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
98
Source/Windows/MainForm.Designer.cs
generated
98
Source/Windows/MainForm.Designer.cs
generated
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -159,6 +159,9 @@
|
|||
<metadata name="toolStripSeparator7.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="toolStripSeparator12.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="menumain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
|
|
Loading…
Reference in a new issue