begun working on EditSelectionMode (unfinished)

This commit is contained in:
codeimp 2008-09-07 21:28:20 +00:00
parent 8a94d9431f
commit eb08197d56
24 changed files with 974 additions and 153 deletions

BIN
Resources/Icons/Warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

View file

@ -107,11 +107,12 @@
<Compile Include="Geometry\Angle2D.cs" />
<Compile Include="Geometry\LinedefsTracePath.cs" />
<Compile Include="Geometry\LinedefAngleSorter.cs" />
<Compile Include="Geometry\Polygon.cs" />
<Compile Include="Geometry\SectorTools.cs" />
<Compile Include="Geometry\Triangulator.cs" />
<Compile Include="Geometry\EarClipVertex.cs" />
<Compile Include="Geometry\Line2D.cs" />
<Compile Include="Geometry\Polygon.cs" />
<Compile Include="Geometry\EarClipPolygon.cs" />
<Compile Include="Geometry\SidedefAngleSorter.cs" />
<Compile Include="Geometry\SidedefsTracePath.cs" />
<Compile Include="Geometry\TriangleList.cs" />
@ -275,6 +276,7 @@
<Compile Include="Controls\NumericTextbox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Windows\MessageBeepType.cs" />
<Compile Include="Windows\OpenMapOptionsForm.cs">
<SubType>Form</SubType>
</Compile>
@ -587,6 +589,8 @@
</ItemGroup>
<ItemGroup>
<Content Include="Resources\DB2.ico" />
<None Include="Resources\Warning.png" />
<None Include="Resources\WarningOff.png" />
<None Include="Resources\Test.png" />
<None Include="Resources\SlimDX_small.png" />
<None Include="Resources\Splash3_trans.png" />

View file

@ -34,6 +34,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ClassicModes\BrightnessMode.cs" />
<Compile Include="ClassicModes\EditSelectionMode.cs" />
<Compile Include="ClassicModes\CurveLinedefsMode.cs" />
<Compile Include="ClassicModes\DragLinedefsMode.cs" />
<Compile Include="ClassicModes\DragSectorsMode.cs" />

View file

@ -395,7 +395,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
// Make polygon
LinedefTracePath tracepath = new LinedefTracePath(pathlines);
Polygon pathpoly = tracepath.MakePolygon();
EarClipPolygon pathpoly = tracepath.MakePolygon();
// Check if the front of the line is outside the polygon
if(!pathpoly.Intersect(ld.GetSidePoint(true)))

View file

@ -0,0 +1,555 @@
#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;
using System.Drawing;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
[EditMode(DisplayName = "Edit Selection",
SwitchAction = "editselectionmode", // Action name used to switch to this mode
ButtonDesc = "Edit Selection Mode", // Description on the button in toolbar/menu
ButtonImage = "LinesMode.png", // Image resource name for the button
Volatile = true,
ButtonOrder = int.MinValue + 210)] // Position of the button (lower is more to the left)
public class EditSelectionMode : ClassicMode
{
#region ================== Enums
private enum ModifyMode : int
{
None,
Dragging,
Resizing
}
private enum Grip : int
{
None,
Main,
SizeN,
SizeS,
SizeE,
SizeW,
RotateLT,
RotateRT,
RotateRB,
RotateLB
}
#endregion
#region ================== Constants
private const float GRIP_SIZE = 11.0f;
private const float BORDER_PADDING = 5.0f;
private readonly Cursor[] RESIZE_CURSORS = { Cursors.SizeNS, Cursors.SizeNESW, Cursors.SizeWE, Cursors.SizeNWSE };
#endregion
#region ================== Variables
// Selection
private ICollection<Vertex> selectedvertices;
private ICollection<Thing> selectedthings;
private List<Vector2D> vertexpos;
private List<Vector2D> thingpos;
// Modification
private float rotation;
private Vector2D offset;
private Vector2D size;
private Vector2D baseoffset;
private Vector2D basesize;
// Modifying Modes
private ModifyMode mode;
private Vector2D dragposition;
private Vector2D resizefilter;
private Vector2D resizevector;
private Line2D resizeaxis;
private bool adjustoffset;
// Rectangle components
private Vector2D[] corners;
private RectangleF[] resizegrips; // top, right, bottom, left
private RectangleF[] rotategrips; // lefttop, righttop, rightbottom, leftbottom
#endregion
#region ================== Properties
#endregion
#region ================== Constructor / Disposer
// Constructor
public EditSelectionMode()
{
// Initialize
mode = ModifyMode.None;
// TEST:
rotation = Angle2D.PI2 * 0.01f;
}
// Disposer
public override void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
// Dispose base
base.Dispose();
}
}
#endregion
#region ================== Events
// Cancel mode
public override void OnCancel()
{
base.OnCancel();
// Return to this mode
General.Map.ChangeMode(new LinedefsMode());
}
// Mode engages
public override void OnEngage()
{
base.OnEngage();
// Convert geometry selection into marked vertices
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);
// 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;
// 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)
{
// Calculate offset and size
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)
{
// Calculate offset and size
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);
}
size = right - offset;
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();
}
}
// Mode disengages
public override void OnDisengage()
{
base.OnDisengage();
// 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);
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))
{
renderer.RenderLine(corners[0], corners[1], 1, General.Colors.Vertices, true);
renderer.RenderLine(corners[1], corners[2], 1, General.Colors.Highlight, true);
renderer.RenderLine(corners[2], corners[3], 1, General.Colors.Highlight, true);
renderer.RenderLine(corners[3], corners[0], 1, General.Colors.Highlight, true);
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.RenderRectangle(rotategrips[0], 2, General.Colors.Vertices, true);
renderer.Finish();
}
renderer.Present();
}
// Mouse moves
public override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// Not in any modifying mode?
if(mode == ModifyMode.None)
{
// Check what grip the mouse is over
// and change cursor accordingly
Grip mousegrip = CheckMouseGrip();
switch(mousegrip)
{
case Grip.Main:
General.Interface.SetCursor(Cursors.Hand);
break;
case Grip.RotateLB:
case Grip.RotateLT:
case Grip.RotateRB:
case Grip.RotateRT:
General.Interface.SetCursor(Cursors.Cross);
break;
case Grip.SizeE:
case Grip.SizeS:
case Grip.SizeW:
case Grip.SizeN:
// Pick the best matching cursor depending on rotation and side
float resizeangle = rotation;
if((mousegrip == Grip.SizeE) || (mousegrip == Grip.SizeW)) resizeangle += Angle2D.PIHALF;
resizeangle = Angle2D.Normalized(resizeangle);
if(resizeangle > Angle2D.PI) resizeangle -= Angle2D.PI;
resizeangle = Math.Abs(resizeangle + Angle2D.PI / 8.000001f);
int cursorindex = (int)Math.Floor((resizeangle / Angle2D.PI) * 4.0f) % 4;
General.Interface.SetCursor(RESIZE_CURSORS[cursorindex]);
break;
default:
General.Interface.SetCursor(Cursors.Default);
break;
}
}
else
{
// Check what modifying mode we are in
switch(mode)
{
// Dragging
case ModifyMode.Dragging:
// Change offset
offset += mousemappos - dragposition;
dragposition = mousemappos;
// Update
UpdateGeometry();
UpdateRectangleComponents();
General.Interface.RedrawDisplay();
break;
// Resizing
case ModifyMode.Resizing:
// Adjust offset if needed
Vector2D oldsize = size;
// Change size
float scale = resizeaxis.GetNearestOnLine(mousemappos);
size = (basesize * resizefilter) * scale + (1.0f - resizefilter) * basesize;
// Adjust offset if needed
if(adjustoffset) offset -= (size - oldsize) * resizevector / basesize.y;
// Update
UpdateGeometry();
UpdateRectangleComponents();
General.Interface.RedrawDisplay();
break;
}
}
}
// Mouse leaves the display
public override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
// Reset cursor
General.Interface.SetCursor(Cursors.Default);
}
// When select button is pressed
protected override void OnSelect()
{
base.OnSelect();
// Check what grip the mouse is over
switch(CheckMouseGrip())
{
// Drag main rectangle
case Grip.Main:
dragposition = mousemappos;
mode = ModifyMode.Dragging;
break;
// Resize
case Grip.SizeN:
// Make the resize axis. This is a line with the length and direction
// of basesize used to calculate the resize percentage.
resizevector = corners[2] - corners[1];
resizevector = resizevector.GetNormal() * basesize.y;
resizeaxis = new Line2D(corners[2], corners[2] + resizevector);
resizefilter = new Vector2D(0.0f, 1.0f);
adjustoffset = true;
mode = ModifyMode.Resizing;
break;
}
}
// When selected button is released
protected override void OnEndSelect()
{
base.OnEndSelect();
// Check what modifying mode we are in
switch(mode)
{
case ModifyMode.Dragging:
General.Interface.RedrawDisplay();
break;
}
mode = ModifyMode.None;
}
#endregion
#region ================== Methods
// This checks and returns the grip the mouse pointer is in
private Grip CheckMouseGrip()
{
// Make polygon from corners
Polygon rectpoly = new Polygon();
rectpoly.AddRange(corners);
if(PointInRectF(resizegrips[0], mousemappos))
return Grip.SizeN;
else if(PointInRectF(resizegrips[2], mousemappos))
return Grip.SizeS;
else if(PointInRectF(resizegrips[1], mousemappos))
return Grip.SizeE;
else if(PointInRectF(resizegrips[3], mousemappos))
return Grip.SizeW;
else if(PointInRectF(rotategrips[0], mousemappos))
return Grip.RotateLT;
else if(PointInRectF(rotategrips[1], mousemappos))
return Grip.RotateRT;
else if(PointInRectF(rotategrips[2], mousemappos))
return Grip.RotateRB;
else if(PointInRectF(rotategrips[3], mousemappos))
return Grip.RotateLB;
else if(rectpoly.Intersect(mousemappos))
return Grip.Main;
else
return Grip.None;
}
// This applies the current rotation and resize to a point
private Vector2D TransformedPoint(Vector2D p)
{
// Resize
p = (p - baseoffset) * (size / basesize) + baseoffset;
// Rotate around center
Vector2D center = baseoffset + basesize * 0.5f;
Vector2D po = p - center;
p.x = (float)Math.Cos(rotation) * po.x + (float)Math.Sin(rotation) * po.y;
p.y = (float)Math.Sin(rotation) * -po.x + (float)Math.Cos(rotation) * po.y;
p += center;
// Move
p += offset - baseoffset;
return p;
}
// This checks if a point is in a rect
private bool PointInRectF(RectangleF rect, Vector2D point)
{
return (point.x >= rect.Left) && (point.x <= rect.Right) && (point.y >= rect.Top) && (point.y <= rect.Bottom);
}
// This moves all things and vertices to match the current transformation
private void UpdateGeometry()
{
int index = 0;
foreach(Vertex v in selectedvertices)
{
v.Move(TransformedPoint(vertexpos[index++]));
}
index = 0;
foreach(Thing t in selectedthings)
{
t.Move(TransformedPoint(thingpos[index++]));
}
General.Map.Map.Update(true, false);
}
// This updates the selection rectangle components
private void UpdateRectangleComponents()
{
float border = BORDER_PADDING / renderer.Scale;
float gripsize = GRIP_SIZE / renderer.Scale;
// Corners
corners = new Vector2D[4];
corners[0] = TransformedPoint(new Vector2D(baseoffset.x - border, baseoffset.y - border));
corners[1] = TransformedPoint(new Vector2D(baseoffset.x - border + basesize.x + border * 2, baseoffset.y - border));
corners[2] = TransformedPoint(new Vector2D(baseoffset.x - border + basesize.x + border * 2, baseoffset.y - border + basesize.y + border * 2));
corners[3] = TransformedPoint(new Vector2D(baseoffset.x - border, baseoffset.y - border + basesize.y + border * 2));
// Middle points between corners
Vector2D middle01 = corners[0] + (corners[1] - corners[0]) * 0.5f;
Vector2D middle12 = corners[1] + (corners[2] - corners[1]) * 0.5f;
Vector2D middle23 = corners[2] + (corners[3] - corners[2]) * 0.5f;
Vector2D middle30 = corners[3] + (corners[0] - corners[3]) * 0.5f;
// Resize grips
resizegrips = new RectangleF[4];
resizegrips[0] = new RectangleF(middle01.x - gripsize * 0.5f,
middle01.y - gripsize * 0.5f,
gripsize, gripsize);
resizegrips[1] = new RectangleF(middle12.x - gripsize * 0.5f,
middle12.y - gripsize * 0.5f,
gripsize, gripsize);
resizegrips[2] = new RectangleF(middle23.x - gripsize * 0.5f,
middle23.y - gripsize * 0.5f,
gripsize, gripsize);
resizegrips[3] = new RectangleF(middle30.x - gripsize * 0.5f,
middle30.y - gripsize * 0.5f,
gripsize, gripsize);
// Rotate grips
rotategrips = new RectangleF[4];
rotategrips[0] = new RectangleF(corners[0].x - gripsize * 0.5f,
corners[0].y - gripsize * 0.5f,
gripsize, gripsize);
rotategrips[1] = new RectangleF(corners[1].x - gripsize * 0.5f,
corners[1].y - gripsize * 0.5f,
gripsize, gripsize);
rotategrips[2] = new RectangleF(corners[2].x - gripsize * 0.5f,
corners[2].y - gripsize * 0.5f,
gripsize, gripsize);
rotategrips[3] = new RectangleF(corners[3].x - gripsize * 0.5f,
corners[3].y - gripsize * 0.5f,
gripsize, gripsize);
}
#endregion
}
}

View file

@ -199,3 +199,12 @@ findmode
allowmouse = true;
allowscroll = true;
}
editselectionmode
{
title = "Edit: Edit Selection Mode";
description = "Allows rotating, resizing and moving a selection.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}

View file

@ -411,7 +411,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
}
// This shows a polygon
private void ShowPolygon(Polygon p, PixelColor c)
private void ShowPolygon(EarClipPolygon p, PixelColor c)
{
LinkedListNode<EarClipVertex> v;

View file

@ -58,6 +58,9 @@ namespace CodeImp.DoomBuilder
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern int SendMessage(IntPtr hwnd, uint Msg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MessageBeep(MessageBeepType type);
#endregion

View file

@ -0,0 +1,165 @@
#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 CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Rendering;
using SlimDX.Direct3D9;
using System.Drawing;
using CodeImp.DoomBuilder.Map;
#endregion
namespace CodeImp.DoomBuilder.Geometry
{
public class EarClipPolygon : LinkedList<EarClipVertex>
{
#region ================== Variables
// Tree variables
private List<EarClipPolygon> children;
private bool inner;
#endregion
#region ================== Properties
public List<EarClipPolygon> Children { get { return children; } }
public bool Inner { get { return inner; } set { inner = value; } }
#endregion
#region ================== Constructors
// Constructor
internal EarClipPolygon()
{
// Initialize
children = new List<EarClipPolygon>();
}
// Constructor
internal EarClipPolygon(EarClipPolygon p, EarClipVertex add) : base(p)
{
// Initialize
base.AddLast(add);
children = new List<EarClipPolygon>();
}
#endregion
#region ================== Methods
// This merges a polygon into this one
public void Add(EarClipPolygon p)
{
// Initialize
foreach(EarClipVertex v in p) base.AddLast(v);
}
// Point inside the polygon?
// See: http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/
public bool Intersect(Vector2D p)
{
float miny, maxy, maxx, xint;
Vector2D v1 = base.Last.Value.Position;
Vector2D v2;
LinkedListNode<EarClipVertex> n = base.First;
uint c = 0;
// Go for all vertices
while(n != null)
{
// Get next vertex
v2 = n.Value.Position;
// Determine min/max values
miny = Math.Min(v1.y, v2.y);
maxy = Math.Max(v1.y, v2.y);
maxx = Math.Max(v1.x, v2.x);
// Check for intersection
if((p.y > miny) && (p.y <= maxy))
{
if(p.x <= maxx)
{
if(v1.y != v2.y)
{
xint = (p.y - v1.y) * (v2.x - v1.x) / (v2.y - v1.y) + v1.x;
if((v1.x == v2.x) || (p.x <= xint)) c++;
}
}
}
// Move to next
v1 = v2;
n = n.Next;
}
// Inside this polygon?
if((c & 0x00000001UL) != 0)
{
// Check if not inside the children
foreach(EarClipPolygon child in children)
{
// Inside this child? Then it is not inside this polygon.
if(child.Intersect(p)) return false;
}
// Inside polygon!
return true;
}
else
{
// Not inside the polygon
return false;
}
}
// This inserts a polygon if it is a child of this one
public bool InsertChild(EarClipPolygon p)
{
// Polygon must have at least 1 vertex
if(p.Count == 0) return false;
// Check if it can be inserted at a lower level
foreach(EarClipPolygon child in children)
{
if(child.InsertChild(p)) return true;
}
// Check if it can be inserted here
if(this.Intersect(p.First.Value.Position))
{
// Make the polygon the inverse of this one
p.Inner = !inner;
children.Add(p);
return true;
}
// Can't insert it as a child
return false;
}
#endregion
}
}

View file

@ -97,9 +97,9 @@ namespace CodeImp.DoomBuilder.Geometry
}
// This makes a polygon from the path
public Polygon MakePolygon()
public EarClipPolygon MakePolygon()
{
Polygon p = new Polygon();
EarClipPolygon p = new EarClipPolygon();
bool forward = true;
// Any sides at all?

View file

@ -31,66 +31,43 @@ using CodeImp.DoomBuilder.Map;
namespace CodeImp.DoomBuilder.Geometry
{
public class Polygon : LinkedList<EarClipVertex>
public class Polygon : List<Vector2D>
{
#region ================== Variables
// Tree variables
private List<Polygon> children;
private bool inner;
#endregion
#region ================== Properties
public List<Polygon> Children { get { return children; } }
public bool Inner { get { return inner; } set { inner = value; } }
#endregion
#region ================== Constructors
// Constructor
internal Polygon()
public Polygon()
{
// Initialize
children = new List<Polygon>();
}
// Constructor
internal Polygon(Polygon p, EarClipVertex add) : base(p)
{
// Initialize
base.AddLast(add);
children = new List<Polygon>();
}
#endregion
#region ================== Methods
// This merges a polygon into this one
public void Add(Polygon p)
{
// Initialize
foreach(EarClipVertex v in p) base.AddLast(v);
}
// Point inside the polygon?
// See: http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/
public bool Intersect(Vector2D p)
{
float miny, maxy, maxx, xint;
Vector2D v1 = base.Last.Value.Position;
Vector2D v1 = base[base.Count - 1];
Vector2D v2;
LinkedListNode<EarClipVertex> n = base.First;
int index = 0;
uint c = 0;
// Go for all vertices
while(n != null)
while(index < base.Count)
{
// Get next vertex
v2 = n.Value.Position;
v2 = base[index];
// Determine min/max values
miny = Math.Min(v1.y, v2.y);
@ -109,57 +86,16 @@ namespace CodeImp.DoomBuilder.Geometry
}
}
}
// Move to next
v1 = v2;
n = n.Next;
index++;
}
// Inside this polygon?
if((c & 0x00000001UL) != 0)
{
// Check if not inside the children
foreach(Polygon child in children)
{
// Inside this child? Then it is not inside this polygon.
if(child.Intersect(p)) return false;
}
// Inside polygon!
return true;
}
else
{
// Not inside the polygon
return false;
}
}
// This inserts a polygon if it is a child of this one
public bool InsertChild(Polygon p)
{
// Polygon must have at least 1 vertex
if(p.Count == 0) return false;
// Check if it can be inserted at a lower level
foreach(Polygon child in children)
{
if(child.InsertChild(p)) return true;
}
// Check if it can be inserted here
if(this.Intersect(p.First.Value.Position))
{
// Make the polygon the inverse of this one
p.Inner = !inner;
children.Add(p);
return true;
}
// Can't insert it as a child
return false;
// Inside this polygon?
return (c & 0x00000001UL) != 0;
}
#endregion
}
}

View file

@ -75,7 +75,7 @@ namespace CodeImp.DoomBuilder.Geometry
List<LinedefSide> alllines = new List<LinedefSide>();
// Find the outer lines
Polygon p = FindOuterLines(line, front, alllines);
EarClipPolygon p = FindOuterLines(line, front, alllines);
if(p != null)
{
// Find the inner lines
@ -87,7 +87,7 @@ namespace CodeImp.DoomBuilder.Geometry
}
// This finds the inner lines of the sector and adds them to the sector polygon
private static void FindInnerLines(Polygon p, List<LinedefSide> alllines)
private static void FindInnerLines(EarClipPolygon p, List<LinedefSide> alllines)
{
Vertex foundv;
bool vvalid, findmore;
@ -169,7 +169,7 @@ namespace CodeImp.DoomBuilder.Geometry
{
// Make polygon
LinedefTracePath tracepath = new LinedefTracePath(innerlines);
Polygon innerpoly = tracepath.MakePolygon();
EarClipPolygon innerpoly = tracepath.MakePolygon();
// Check if the front of the line is outside the polygon
if(!innerpoly.Intersect(foundline.GetSidePoint(foundlinefront)))
@ -188,7 +188,7 @@ namespace CodeImp.DoomBuilder.Geometry
// This finds the outer lines of the sector as a polygon
// Returns null when no valid outer polygon can be found
private static Polygon FindOuterLines(Linedef line, bool front, List<LinedefSide> alllines)
private static EarClipPolygon FindOuterLines(Linedef line, bool front, List<LinedefSide> alllines)
{
Linedef scanline = line;
bool scanfront = front;
@ -201,7 +201,7 @@ namespace CodeImp.DoomBuilder.Geometry
{
// Make polygon
LinedefTracePath tracepath = new LinedefTracePath(pathlines);
Polygon poly = tracepath.MakePolygon();
EarClipPolygon poly = tracepath.MakePolygon();
// Check if the front of the line is inside the polygon
if(poly.Intersect(line.GetSidePoint(front)))

View file

@ -84,9 +84,9 @@ namespace CodeImp.DoomBuilder.Geometry
}
// This makes a polygon from the path
public Polygon MakePolygon()
public EarClipPolygon MakePolygon()
{
Polygon p = new Polygon();
EarClipPolygon p = new EarClipPolygon();
// Any sides at all?
if(base.Count > 0)

View file

@ -43,7 +43,7 @@ namespace CodeImp.DoomBuilder.Geometry
// For debugging purpose only!
// These are not called in a release build
public delegate void ShowLine(Vector2D v1, Vector2D v2, PixelColor c);
public delegate void ShowPolygon(Polygon p, PixelColor c);
public delegate void ShowPolygon(EarClipPolygon p, PixelColor c);
public delegate void ShowPoint(Vector2D v, int c);
public delegate void ShowEarClip(EarClipVertex[] found, LinkedList<EarClipVertex> remaining);
@ -87,7 +87,7 @@ namespace CodeImp.DoomBuilder.Geometry
public TriangleList PerformTriangulation(Sector sector)
{
TriangleList triangles = new TriangleList();
List<Polygon> polys;
List<EarClipPolygon> polys;
/*
* This process is divided into several steps:
@ -110,7 +110,7 @@ namespace CodeImp.DoomBuilder.Geometry
DoCutting(polys);
// EAR-CLIPPING
foreach(Polygon p in polys) triangles.AddRange(DoEarClip(p));
foreach(EarClipPolygon p in polys) triangles.AddRange(DoEarClip(p));
// Return result
return triangles;
@ -121,13 +121,13 @@ namespace CodeImp.DoomBuilder.Geometry
#region ================== Tracing
// This traces sector lines to create a polygon tree
private List<Polygon> DoTrace(Sector s)
private List<EarClipPolygon> DoTrace(Sector s)
{
Dictionary<Sidedef, bool> todosides = new Dictionary<Sidedef, bool>(s.Sidedefs.Count);
Dictionary<Vertex, Vertex> ignores = new Dictionary<Vertex,Vertex>();
List<Polygon> root = new List<Polygon>();
List<EarClipPolygon> root = new List<EarClipPolygon>();
SidedefsTracePath path;
Polygon newpoly;
EarClipPolygon newpoly;
Vertex start;
// Fill the dictionary
@ -174,7 +174,7 @@ namespace CodeImp.DoomBuilder.Geometry
#endif
// Determine where this polygon goes in our tree
foreach(Polygon p in root)
foreach(EarClipPolygon p in root)
{
// Insert if it belongs as a child
if(p.InsertChild(newpoly))
@ -333,26 +333,26 @@ namespace CodeImp.DoomBuilder.Geometry
#region ================== Cutting
// This cuts into outer polygons to solve inner polygons and make the polygon tree flat
private void DoCutting(List<Polygon> polys)
private void DoCutting(List<EarClipPolygon> polys)
{
Queue<Polygon> todo = new Queue<Polygon>(polys);
Queue<EarClipPolygon> todo = new Queue<EarClipPolygon>(polys);
// Begin processing outer polygons
while(todo.Count > 0)
{
// Get outer polygon to process
Polygon p = todo.Dequeue();
EarClipPolygon p = todo.Dequeue();
// Any inner polygons to work with?
if(p.Children.Count > 0)
{
// Go for all the children
foreach(Polygon c in p.Children)
foreach(EarClipPolygon c in p.Children)
{
// The children of the children are outer polygons again,
// so move them to the root and add for processing
polys.AddRange(c.Children);
foreach(Polygon sc in c.Children) todo.Enqueue(sc);
foreach(EarClipPolygon sc in c.Children) todo.Enqueue(sc);
// Remove from inner polygon
c.Children.Clear();
@ -365,12 +365,12 @@ namespace CodeImp.DoomBuilder.Geometry
}
// This takes an outer polygon and a set of inner polygons to start cutting on
private void MergeInnerPolys(Polygon p)
private void MergeInnerPolys(EarClipPolygon p)
{
LinkedList<Polygon> todo = new LinkedList<Polygon>(p.Children);
LinkedList<EarClipPolygon> todo = new LinkedList<EarClipPolygon>(p.Children);
LinkedListNode<EarClipVertex> start;
LinkedListNode<Polygon> ip;
LinkedListNode<Polygon> found;
LinkedListNode<EarClipPolygon> ip;
LinkedListNode<EarClipPolygon> found;
LinkedListNode<EarClipVertex> foundstart;
// Continue until no more inner polygons to process
@ -406,7 +406,7 @@ namespace CodeImp.DoomBuilder.Geometry
}
// This finds the right-most vertex in an inner polygon to use for cut startpoint.
private static LinkedListNode<EarClipVertex> FindRightMostVertex(Polygon p)
private static LinkedListNode<EarClipVertex> FindRightMostVertex(EarClipPolygon p)
{
LinkedListNode<EarClipVertex> found = p.First;
LinkedListNode<EarClipVertex> v = found.Next;
@ -423,7 +423,7 @@ namespace CodeImp.DoomBuilder.Geometry
}
// This finds the cut coordinates and splits the other poly with inner vertices
private static void SplitOuterWithInner(LinkedListNode<EarClipVertex> start, Polygon p, Polygon inner)
private static void SplitOuterWithInner(LinkedListNode<EarClipVertex> start, EarClipPolygon p, EarClipPolygon inner)
{
Line2D starttoright = new Line2D(start.Value.Position, start.Value.Position + new Vector2D(1000.0f, 0.0f));
LinkedListNode<EarClipVertex> v1, v2;
@ -516,7 +516,7 @@ namespace CodeImp.DoomBuilder.Geometry
// This clips a polygon and returns the triangles
// The polygon may not have any holes or islands
private TriangleList DoEarClip(Polygon poly)
private TriangleList DoEarClip(EarClipPolygon poly)
{
LinkedList<EarClipVertex> verts = new LinkedList<EarClipVertex>();
List<EarClipVertex> convexes = new List<EarClipVertex>(poly.Count);

View file

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1433
// Runtime Version:2.0.50727.832
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -235,6 +235,20 @@ namespace CodeImp.DoomBuilder.Properties {
}
}
internal static System.Drawing.Bitmap Warning {
get {
object obj = ResourceManager.GetObject("Warning", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap WarningOff {
get {
object obj = ResourceManager.GetObject("WarningOff", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Zoom {
get {
object obj = ResourceManager.GetObject("Zoom", resourceCulture);

View file

@ -196,4 +196,10 @@
<data name="Test" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Test.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Warning" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Warning.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="WarningOff" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\WarningOff.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

View file

@ -70,7 +70,10 @@ namespace CodeImp.DoomBuilder.Windows
void ResumeExclusiveMouseInput();
bool CheckActionActive(Assembly assembly, string actionname);
void SetCursor(Cursor cursor);
void DisplayWarning(string warning);
void HideWarning();
void MessageBeep(MessageBeepType type);
/// <summary>
/// This browses the lindef types
/// </summary>

View file

@ -91,6 +91,7 @@ namespace CodeImp.DoomBuilder.Windows
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.statusbar = new System.Windows.Forms.StatusStrip();
this.statuslabel = new System.Windows.Forms.ToolStripStatusLabel();
this.warninglabel = 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();
@ -123,6 +124,8 @@ namespace CodeImp.DoomBuilder.Windows
this.redrawtimer = new System.Windows.Forms.Timer(this.components);
this.display = new CodeImp.DoomBuilder.Controls.RenderTargetControl();
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);
toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
@ -239,7 +242,7 @@ namespace CodeImp.DoomBuilder.Windows
this.menuhelp});
this.menumain.Location = new System.Drawing.Point(0, 0);
this.menumain.Name = "menumain";
this.menumain.Size = new System.Drawing.Size(823, 24);
this.menumain.Size = new System.Drawing.Size(961, 24);
this.menumain.TabIndex = 0;
//
// menufile
@ -514,7 +517,7 @@ namespace CodeImp.DoomBuilder.Windows
this.toolStripSeparator6});
this.toolbar.Location = new System.Drawing.Point(0, 24);
this.toolbar.Name = "toolbar";
this.toolbar.Size = new System.Drawing.Size(823, 25);
this.toolbar.Size = new System.Drawing.Size(961, 25);
this.toolbar.TabIndex = 1;
//
// buttonnewmap
@ -669,6 +672,7 @@ namespace CodeImp.DoomBuilder.Windows
this.statusbar.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.statusbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.statuslabel,
this.warninglabel,
this.gridlabel,
this.buttongrid,
toolStripSeparator1,
@ -678,10 +682,10 @@ namespace CodeImp.DoomBuilder.Windows
this.xposlabel,
this.poscommalabel,
this.yposlabel});
this.statusbar.Location = new System.Drawing.Point(0, 522);
this.statusbar.Location = new System.Drawing.Point(0, 611);
this.statusbar.Name = "statusbar";
this.statusbar.ShowItemToolTips = true;
this.statusbar.Size = new System.Drawing.Size(823, 23);
this.statusbar.Size = new System.Drawing.Size(961, 23);
this.statusbar.TabIndex = 2;
//
// statuslabel
@ -690,17 +694,29 @@ 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(497, 18);
this.statuslabel.Size = new System.Drawing.Size(571, 18);
this.statuslabel.Spring = true;
this.statuslabel.Text = "Initializing user interface...";
this.statuslabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// warninglabel
//
this.warninglabel.BackColor = System.Drawing.SystemColors.Control;
this.warninglabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Warning;
this.warninglabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.warninglabel.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.warninglabel.Name = "warninglabel";
this.warninglabel.Size = new System.Drawing.Size(167, 18);
this.warninglabel.Text = "Make a selection first!";
this.warninglabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.warninglabel.Visible = false;
//
// gridlabel
//
this.gridlabel.AutoSize = false;
this.gridlabel.AutoToolTip = true;
this.gridlabel.Name = "gridlabel";
this.gridlabel.Size = new System.Drawing.Size(64, 18);
this.gridlabel.Size = new System.Drawing.Size(128, 18);
this.gridlabel.Text = "32 mp";
this.gridlabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.gridlabel.TextImageRelation = System.Windows.Forms.TextImageRelation.Overlay;
@ -916,9 +932,9 @@ namespace CodeImp.DoomBuilder.Windows
this.panelinfo.Controls.Add(this.sectorinfo);
this.panelinfo.Controls.Add(this.linedefinfo);
this.panelinfo.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panelinfo.Location = new System.Drawing.Point(0, 416);
this.panelinfo.Location = new System.Drawing.Point(0, 505);
this.panelinfo.Name = "panelinfo";
this.panelinfo.Size = new System.Drawing.Size(823, 106);
this.panelinfo.Size = new System.Drawing.Size(961, 106);
this.panelinfo.TabIndex = 4;
//
// modename
@ -993,7 +1009,7 @@ namespace CodeImp.DoomBuilder.Windows
this.display.Dock = System.Windows.Forms.DockStyle.Fill;
this.display.Location = new System.Drawing.Point(0, 49);
this.display.Name = "display";
this.display.Size = new System.Drawing.Size(823, 367);
this.display.Size = new System.Drawing.Size(961, 456);
this.display.TabIndex = 5;
this.display.MouseLeave += new System.EventHandler(this.display_MouseLeave);
this.display.MouseDown += new System.Windows.Forms.MouseEventHandler(this.display_MouseDown);
@ -1010,10 +1026,18 @@ namespace CodeImp.DoomBuilder.Windows
this.processor.Interval = 10;
this.processor.Tick += new System.EventHandler(this.processor_Tick);
//
// warningtimer
//
this.warningtimer.Tick += new System.EventHandler(this.warningtimer_Tick);
//
// warningflasher
//
this.warningflasher.Tick += new System.EventHandler(this.warningflasher_Tick);
//
// MainForm
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(823, 545);
this.ClientSize = new System.Drawing.Size(961, 634);
this.Controls.Add(this.display);
this.Controls.Add(this.panelinfo);
this.Controls.Add(this.statusbar);
@ -1131,5 +1155,8 @@ namespace CodeImp.DoomBuilder.Windows
private System.Windows.Forms.ToolStripMenuItem itemgriddec;
private System.Windows.Forms.ToolStripMenuItem itemgridsetup;
private System.Windows.Forms.Label modename;
private System.Windows.Forms.ToolStripStatusLabel warninglabel;
private System.Windows.Forms.Timer warningtimer;
private System.Windows.Forms.Timer warningflasher;
}
}

View file

@ -34,6 +34,7 @@ using System.Reflection;
using CodeImp.DoomBuilder.Plugins;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Properties;
#endregion
@ -46,7 +47,8 @@ namespace CodeImp.DoomBuilder.Windows
private const string STATUS_READY_TEXT = "Ready.";
private const int MAX_RECENT_FILES = 8;
private const int MAX_RECENT_FILES_PIXELS = 250;
private const int WARNING_FLASH_COUNT = 5;
#endregion
#region ================== Delegates
@ -82,6 +84,10 @@ namespace CodeImp.DoomBuilder.Windows
private EventHandler buttonvisiblechangedhandler;
private bool updatingfilters;
// Statusbar
private int warningflashcount;
private bool warningsignon;
#endregion
#region ================== Properties
@ -136,6 +142,12 @@ namespace CodeImp.DoomBuilder.Windows
#region ================== General
// This makes a beep sound
public void MessageBeep(MessageBeepType type)
{
General.MessageBeep(type);
}
// This updates all menus for the current status
internal void UpdateInterface()
{
@ -306,6 +318,9 @@ namespace CodeImp.DoomBuilder.Windows
if(General.CloseMap())
{
General.WriteLogLine("Closing main interface window...");
// Hide warning to stop timers
HideWarning();
// Stop exclusive mode, if any is active
StopExclusiveMouseInput();
@ -380,10 +395,70 @@ namespace CodeImp.DoomBuilder.Windows
{
return statuslabel.Text;
}
// This shows a warning
public void DisplayWarning(string warning)
{
MessageBeep(MessageBeepType.Warning);
warninglabel.Spring = true;
warninglabel.Text = warning;
warninglabel.Image = Resources.Warning;
warninglabel.Visible = true;
warningflashcount = 0;
warningsignon = true;
warningtimer.Stop();
warningtimer.Interval = 3000;
warningtimer.Start();
warningflasher.Start();
}
// This hides any warning
public void HideWarning()
{
warningtimer.Stop();
warninglabel.Visible = false;
warninglabel.Spring = false;
warningflasher.Stop();
}
// This flashes the warning sign
private void warningflasher_Tick(object sender, EventArgs e)
{
// Warning sign on?
if(warningsignon)
{
// Turn it off or should we stop?
if(warningflashcount < WARNING_FLASH_COUNT)
{
warninglabel.Image = Resources.WarningOff;
warningsignon = false;
}
else
{
warningflasher.Stop();
}
}
else
{
// Turn it on and count the flash
warninglabel.Image = Resources.Warning;
warningsignon = true;
warningflashcount++;
}
}
// Warning timed out
private void warningtimer_Tick(object sender, EventArgs e)
{
HideWarning();
}
// This changes status text
public void DisplayStatus(string status)
{
// Hide any warning
HideWarning();
// Update status description
if(statuslabel.Text != status)
statuslabel.Text = status;

View file

@ -156,53 +156,26 @@
<metadata name="toolStripSeparator2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="menumain.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</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>
<metadata name="toolbar.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="toolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>121, 17</value>
</metadata>
<metadata name="statusbar.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="statusbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>207, 17</value>
</metadata>
<metadata name="panelinfo.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="modename.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="vertexinfo.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="thinginfo.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="sectorinfo.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="linedefinfo.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="redrawtimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>304, 17</value>
</metadata>
<metadata name="display.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="processor.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>416, 17</value>
</metadata>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
<metadata name="warningtimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>515, 17</value>
</metadata>
<metadata name="warningflasher.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>632, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">

View file

@ -0,0 +1,50 @@
#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 System.Drawing;
using System.ComponentModel;
using CodeImp.DoomBuilder.Map;
using SlimDX.Direct3D9;
using SlimDX;
using CodeImp.DoomBuilder.Geometry;
using System.Drawing.Imaging;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Editing;
#endregion
namespace CodeImp.DoomBuilder.Windows
{
public enum MessageBeepType : int
{
Default = -1,
Ok = 0x00000000,
Error = 0x00000010,
Question = 0x00000020,
Warning = 0x00000030,
Information = 0x00000040,
}
}