Added Draw Curve mode.

This commit is contained in:
MaxED 2013-04-08 13:28:04 +00:00
parent 466ff329df
commit 818a485ec2
8 changed files with 645 additions and 12 deletions

View file

@ -696,6 +696,7 @@
<Compile Include="General\ErrorItem.cs" />
<Compile Include="General\ErrorLogger.cs" />
<Compile Include="General\SavePurpose.cs" />
<Compile Include="Geometry\CurveTools.cs" />
<Compile Include="GZBuilder\Controls\CustomLinedefColorProperties.cs">
<SubType>UserControl</SubType>
</Compile>

View file

@ -0,0 +1,359 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CodeImp.DoomBuilder.Geometry
{
/// <summary>
/// mxd. Tools to work with curves.
/// </summary>
public static class CurveTools
{
//mxd. Ported from Cubic Bezier curve tools by Andy Woodruff (http://cartogrammar.com/source/CubicBezier.as)
//"default" values: z = 0.5, angleFactor = 0.75; if targetSegmentLength <= 0, will return lines
public static Curve CurveThroughPoints(List<Vector2D> points, float z, float angleFactor, int targetSegmentLength) {
Curve result = new Curve();
// First calculate all the curve control points
// None of this junk will do any good if there are only two points
if(points.Count > 2 && targetSegmentLength > 0) {
List<List<Vector2D>> controlPts = new List<List<Vector2D>>(); // An array to store the two control points (of a cubic Bézier curve) for each point
// Make sure z is between 0 and 1 (too messy otherwise)
if(z <= 0)
z = 0.1f;
else if(z > 1)
z = 1;
// Make sure angleFactor is between 0 and 1
if(angleFactor < 0)
angleFactor = 0;
else if(angleFactor > 1)
angleFactor = 1;
// Ordinarily, curve calculations will start with the second point and go through the second-to-last point
int firstPt = 1;
int lastPt = points.Count - 1;
// Check if this is a closed line (the first and last points are the same)
if(points[0].x == points[points.Count - 1].x && points[0].y == points[points.Count - 1].y) {
// Include first and last points in curve calculations
firstPt = 0;
lastPt = points.Count;
} else {
controlPts.Add(new List<Vector2D>()); //add a dummy entry
}
// Loop through all the points (except the first and last if not a closed line) to get curve control points for each.
for(int i = firstPt; i < lastPt; i++) {
// The previous, current, and next points
Vector2D p0 = (i - 1 < 0) ? points[points.Count - 2] : points[i - 1]; // If the first point (of a closed line), use the second-to-last point as the previous point
Vector2D p1 = points[i];
Vector2D p2 = (i + 1 == points.Count) ? points[1] : points[i + 1]; // If the last point (of a closed line), use the second point as the next point
float a = Vector2D.Distance(p0, p1); // Distance from previous point to current point
if(a < 0.001)
a = 0.001f; // Correct for near-zero distances, a cheap way to prevent division by zero
float b = Vector2D.Distance(p1, p2); // Distance from current point to next point
if(b < 0.001)
b = 0.001f;
float c = Vector2D.Distance(p0, p2); // Distance from previous point to next point
if(c < 0.001)
c = 0.001f;
float cos = (b * b + a * a - c * c) / (2 * b * a);
// Make sure above value is between -1 and 1 so that Math.acos will work
if(cos < -1)
cos = -1;
else if(cos > 1)
cos = 1;
float C = (float)Math.Acos(cos); // Angle formed by the two sides of the triangle (described by the three points above) adjacent to the current point
// Duplicate set of points. Start by giving previous and next points values RELATIVE to the current point.
Vector2D aPt = new Vector2D(p0.x - p1.x, p0.y - p1.y);
Vector2D bPt = new Vector2D(p1.x, p1.y);
Vector2D cPt = new Vector2D(p2.x - p1.x, p2.y - p1.y);
/*
We'll be adding adding the vectors from the previous and next points to the current point,
but we don't want differing magnitudes (i.e. line segment lengths) to affect the direction
of the new vector. Therefore we make sure the segments we use, based on the duplicate points
created above, are of equal length. The angle of the new vector will thus bisect angle C
(defined above) and the perpendicular to this is nice for the line tangent to the curve.
The curve control points will be along that tangent line.
*/
if(a > b)
aPt = aPt.GetNormal() * b; // Scale the segment to aPt (bPt to aPt) to the size of b (bPt to cPt) if b is shorter.
else if(b > a)
cPt = cPt.GetNormal() * a; // Scale the segment to cPt (bPt to cPt) to the size of a (aPt to bPt) if a is shorter.
// Offset aPt and cPt by the current point to get them back to their absolute position.
aPt += p1;
cPt += p1;
// Get the sum of the two vectors, which is perpendicular to the line along which our curve control points will lie.
float ax = bPt.x - aPt.x; // x component of the segment from previous to current point
float ay = bPt.y - aPt.y;
float bx = bPt.x - cPt.x; // x component of the segment from next to current point
float by = bPt.y - cPt.y;
float rx = ax + bx; // sum of x components
float ry = ay + by;
// Correct for three points in a line by finding the angle between just two of them
if(rx == 0 && ry == 0) {
rx = -bx; // Really not sure why this seems to have to be negative
ry = by;
}
// Switch rx and ry when y or x difference is 0. This seems to prevent the angle from being perpendicular to what it should be.
if(ay == 0 && by == 0) {
rx = 0;
ry = 1;
} else if(ax == 0 && bx == 0) {
rx = 1;
ry = 0;
}
float r = (float)Math.Sqrt(rx * rx + ry * ry); // length of the summed vector - not being used, but there it is anyway
float theta = (float)Math.Atan2(ry, rx); // angle of the new vector
float controlDist = Math.Min(a, b) * z; // Distance of curve control points from current point: a fraction the length of the shorter adjacent triangle side
float controlScaleFactor = C / (float)Math.PI; // Scale the distance based on the acuteness of the angle. Prevents big loops around long, sharp-angled triangles.
controlDist *= ((1 - angleFactor) + angleFactor * controlScaleFactor); // Mess with this for some fine-tuning
float controlAngle = theta + (float)Math.PI / 2; // The angle from the current point to control points: the new vector angle plus 90 degrees (tangent to the curve).
Vector2D controlPoint2 = new Vector2D(controlDist, 0);
Vector2D controlPoint1 = new Vector2D(controlDist, 0);
controlPoint2 = controlPoint2.GetRotated(controlAngle);
controlPoint1 = controlPoint1.GetRotated(controlAngle + (float)Math.PI);
// Offset control points to put them in the correct absolute position
controlPoint1 += p1;
controlPoint2 += p1;
/*
Haven't quite worked out how this happens, but some control points will be reversed.
In this case controlPoint2 will be farther from the next point than controlPoint1 is.
Check for that and switch them if it's true.
*/
if(Vector2D.Distance(controlPoint2, p2) > Vector2D.Distance(controlPoint1, p2))
controlPts.Add(new List<Vector2D>() { controlPoint2, controlPoint1 });
else
controlPts.Add(new List<Vector2D>() { controlPoint1, controlPoint2 });
}
// If this isn't a closed line, draw a regular quadratic Bézier curve from the first to second points, using the first control point of the second point
if(firstPt == 1) {
float length = (points[1] - points[0]).GetLength();
int numSteps = Math.Max(1, (int)Math.Round(length / targetSegmentLength));
CurveSegment segment = new CurveSegment();
segment.Start = points[0];
segment.CPMid = controlPts[1][0];
segment.End = points[1];
CreateQuadraticCurve(segment, numSteps);
result.Segments.Add(segment);
}
// Loop through points to draw cubic Bézier curves through the penultimate point, or through the last point if the line is closed.
for(int i = firstPt; i < lastPt - 1; i++) {
float length = (points[i + 1] - points[i]).GetLength();
int numSteps = Math.Max(1, (int)Math.Round(length / targetSegmentLength));
CurveSegment segment = new CurveSegment();
segment.CPStart = controlPts[i][1];
segment.CPEnd = controlPts[i + 1][0];
segment.Start = points[i];
segment.End = points[i + 1];
CreateCubicCurve(segment, numSteps);
result.Segments.Add(segment);
}
// If this isn't a closed line, curve to the last point using the second control point of the penultimate point.
if(lastPt == points.Count - 1) {
float length = (points[lastPt] - points[lastPt - 1]).GetLength();
int numSteps = Math.Max(1, (int)Math.Round(length / targetSegmentLength));
CurveSegment segment = new CurveSegment();
segment.Start = points[lastPt - 1];
segment.CPMid = controlPts[lastPt - 1][1];
segment.End = points[lastPt];
CreateQuadraticCurve(segment, numSteps);
result.Segments.Add(segment);
}
// create lines
} else if(points.Count >= 2) {
for(int i = 0; i < points.Count - 1; i++) {
CurveSegment segment = new CurveSegment();
segment.Start = points[i];
segment.End = points[i + 1];
segment.Points = new Vector2D[] { segment.Start, segment.End };
segment.UpdateLength();
result.Segments.Add(segment);
}
}
result.UpdateShape();
return result;
}
public static void CreateQuadraticCurve(CurveSegment segment, int steps) {
segment.CurveType = CurveSegmentType.QUADRATIC;
segment.Points = GetQuadraticCurve(segment.Start, segment.CPMid, segment.End, steps);
segment.UpdateLength();
}
//this returns array of Vector2D to draw 3-point bezier curve
public static Vector2D[] GetQuadraticCurve(Vector2D p1, Vector2D p2, Vector2D p3, int steps) {
if(steps < 0)
return null;
int totalSteps = steps + 1;
Vector2D[] points = new Vector2D[totalSteps];
float step = 1f / (float)steps;
float curStep = 0f;
for(int i = 0; i < totalSteps; i++) {
points[i] = GetPointOnQuadraticCurve(p1, p2, p3, curStep);
curStep += step;
}
return points;
}
public static void CreateCubicCurve(CurveSegment segment, int steps) {
segment.CurveType = CurveSegmentType.CUBIC;
segment.Points = GetCubicCurve(segment.Start, segment.End, segment.CPStart, segment.CPEnd, steps);
segment.UpdateLength();
}
//this returns array of Vector2D to draw 4-point bezier curve
public static Vector2D[] GetCubicCurve(Vector2D p1, Vector2D p2, Vector2D cp1, Vector2D cp2, int steps) {
if(steps < 0)
return null;
int totalSteps = steps + 1;
Vector2D[] points = new Vector2D[totalSteps];
float step = 1f / (float)steps;
float curStep = 0f;
for(int i = 0; i < totalSteps; i++) {
points[i] = GetPointOnCubicCurve(p1, p2, cp1, cp2, curStep);
curStep += step;
}
return points;
}
public static Vector2D GetPointOnCurve(CurveSegment segment, float delta) {
if(segment.CurveType == CurveSegmentType.QUADRATIC)
return GetPointOnQuadraticCurve(segment.Start, segment.CPMid, segment.End, delta);
if(segment.CurveType == CurveSegmentType.CUBIC)
return GetPointOnCubicCurve(segment.Start, segment.End, segment.CPStart, segment.CPEnd, delta);
if(segment.CurveType == CurveSegmentType.LINE)
return GetPointOnLine(segment.Start, segment.End, delta);
throw new Exception("GetPointOnCurve: got unknown curve type: " + segment.CurveType);
}
public static Vector2D GetPointOnQuadraticCurve(Vector2D p1, Vector2D p2, Vector2D p3, float delta) {
float invDelta = 1f - delta;
float m1 = invDelta * invDelta;
float m2 = 2 * invDelta * delta;
float m3 = delta * delta;
int px = (int)(m1 * p1.x + m2 * p2.x + m3 * p3.x);
int py = (int)(m1 * p1.y + m2 * p2.y + m3 * p3.y);
return new Vector2D(px, py);
}
public static Vector2D GetPointOnCubicCurve(Vector2D p1, Vector2D p2, Vector2D cp1, Vector2D cp2, float delta) {
float invDelta = 1f - delta;
float m1 = invDelta * invDelta * invDelta;
float m2 = 3 * delta * invDelta * invDelta;
float m3 = 3 * delta * delta * invDelta;
float m4 = delta * delta * delta;
int px = (int)(m1 * p1.x + m2 * cp1.x + m3 * cp2.x + m4 * p2.x);
int py = (int)(m1 * p1.y + m2 * cp1.y + m3 * cp2.y + m4 * p2.y);
return new Vector2D(px, py);
}
//it's basically 2-point bezier curve
public static Vector2D GetPointOnLine(Vector2D p1, Vector2D p2, float delta) {
return new Vector2D((int)((1f - delta) * p1.x + delta * p2.x), (int)((1f - delta) * p1.y + delta * p2.y));
}
}
public class Curve
{
public List<CurveSegment> Segments;
public List<Vector2D> Shape;
public float Length;
public Curve() {
Segments = new List<CurveSegment>();
}
public void UpdateShape() {
Shape = new List<Vector2D>();
Length = 0;
foreach(CurveSegment segment in Segments) {
Length += segment.Length;
foreach(Vector2D point in segment.Points) {
if(Shape.Count == 0 || point != Shape[Shape.Count - 1])
Shape.Add(point);
}
}
float curDelta = 0;
for(int i = 0; i < Segments.Count; i++) {
Segments[i].Delta = Segments[i].Length / Length;
curDelta += Segments[i].Delta;
Segments[i].GlobalDelta = curDelta;
}
}
}
public class CurveSegment
{
public Vector2D[] Points;
public Vector2D Start;
public Vector2D End;
public Vector2D CPStart;
public Vector2D CPMid;
public Vector2D CPEnd;
public float Length;
public float Delta; //length of this segment / total curve length
public float GlobalDelta; //length of this segment / total curve length + deltas of previous segments
public CurveSegmentType CurveType;
public void UpdateLength() {
if(Points.Length < 2)
return;
Length = 0;
for(int i = 1; i < Points.Length; i++)
Length += Vector2D.Distance(Points[i], Points[i - 1]);
}
}
public enum CurveSegmentType
{
LINE,
QUADRATIC,
CUBIC,
}
}

View file

@ -226,6 +226,7 @@
<ItemGroup>
<Compile Include="ClassicModes\BridgeMode.cs" />
<Compile Include="ClassicModes\CeilingAlignMode.cs" />
<Compile Include="ClassicModes\DrawCurveMode.cs" />
<Compile Include="ClassicModes\DrawEllipseMode.cs" />
<Compile Include="ClassicModes\DrawRectangleMode.cs" />
<Compile Include="ClassicModes\FlatAlignMode.cs" />
@ -396,6 +397,9 @@
<ItemGroup>
<None Include="Resources\AlignThings.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\DrawCurveMode.png" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -0,0 +1,246 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Windows;
namespace CodeImp.DoomBuilder.BuilderModes.ClassicModes
{
[EditMode(DisplayName = "Draw Curve Mode",
SwitchAction = "drawcurvemode",
AllowCopyPaste = false,
Volatile = true,
Optional = false)]
public class DrawCurveMode : DrawGeometryMode
{
private HintLabel hintLabel;
private Curve curve;
private static int segmentLength = 32;
private int minSegmentLength = 16;
private int maxSegmentLength = 4096; //just some arbitrary number
public DrawCurveMode() : base() {
hintLabel = new HintLabel();
}
public override void Dispose() {
if(!isdisposed && hintLabel != null)
hintLabel.Dispose();
base.Dispose();
}
protected override 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 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) {
//update curve
List<Vector2D> verts = new List<Vector2D>();
for(int i = 0; i < points.Count; i++)
verts.Add(points[i].pos);
if(curp.pos != verts[verts.Count-1])
verts.Add(curp.pos);
curve = CurveTools.CurveThroughPoints(verts, 0.5f, 0.75f, segmentLength);
// Render lines
for(int i = 1; i < curve.Shape.Count; i++) {
// Determine line color
color = snaptonearest ? stitchcolor : losecolor;
// Render line
renderer.RenderLine(curve.Shape[i - 1], curve.Shape[i], LINE_THICKNESS, color, true);
}
//render "inactive" vertices
for(int i = 1; i < curve.Shape.Count - 1; i++) {
// Determine vertex color
color = !snaptonearest ? stitchcolor : losecolor;
// Render vertex
renderer.RenderRectangleFilled(new RectangleF(curve.Shape[i].x - vsize, curve.Shape[i].y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
}
}
if(points.Count > 0) {
// Render vertices
for(int i = 0; i < points.Count; i++) {
// Determine vertex color
color = points[i].stitch ? stitchcolor : losecolor;
// Render vertex
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
color = snaptonearest ? stitchcolor : 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);
//Render info label
hintLabel.Start = new Vector2D(mousemappos.x + (32 / renderer.Scale), mousemappos.y - (16 / renderer.Scale));
hintLabel.End = new Vector2D(mousemappos.x + (96 / renderer.Scale), mousemappos.y);
hintLabel.Text = "SEG LEN: " + segmentLength;
renderer.RenderText(hintLabel.TextLabel);
// Done
renderer.Finish();
}
// Done
renderer.Present();
}
public override void OnAccept() {
Cursor.Current = Cursors.AppStarting;
General.Settings.FindDefaultDrawSettings();
// When points have been drawn
if(points.Count > 0) {
// Make undo for the draw
General.Map.UndoRedo.CreateUndo("Curve draw");
// Make an analysis and show info
string[] adjectives = new string[]
{ "beautiful", "lovely", "romantic", "stylish", "cheerful", "comical",
"awesome", "accurate", "adorable", "adventurous", "attractive", "cute",
"elegant", "glamorous", "gorgeous", "handsome", "magnificent", "unusual",
"outstanding", "mysterious", "amusing", "charming", "fantastic", "jolly" };
string word = adjectives[points.Count % adjectives.Length];
word = (points.Count > adjectives.Length) ? "very " + word : word;
string a = ((word[0] == 'a') || (word[0] == 'e') || (word[0] == 'o')) ? "an " : "a ";
General.Interface.DisplayStatus(StatusType.Action, "Created " + a + word + " drawing.");
List<DrawnVertex> verts = new List<DrawnVertex>();
//if we have a curve...
if(points.Count > 2){
//is it a closed curve?
int lastPoint = 0;
if(points[0].pos == points[points.Count - 1].pos) {
lastPoint = curve.Segments.Count;
} else {
lastPoint = curve.Segments.Count - 1;
}
for(int i = 0; i < lastPoint; i++) {
int next = (i == curve.Segments.Count - 1 ? 0 : i + 1);
bool stitch = points[i].stitch && points[next].stitch;
bool stitchline = points[i].stitchline && points[next].stitchline;
//add segment points except the last one
for(int c = 0; c < curve.Segments[i].Points.Length - 1; c++) {
DrawnVertex dv = new DrawnVertex();
dv.pos = curve.Segments[i].Points[c];
dv.stitch = stitch;
dv.stitchline = stitchline;
verts.Add(dv);
}
}
//add last point
DrawnVertex end = new DrawnVertex();
end.pos = curve.Segments[lastPoint - 1].End;
end.stitch = verts[verts.Count - 1].stitch;
end.stitchline = verts[verts.Count - 1].stitchline;
verts.Add(end);
}else{
verts = points;
}
// Make the drawing
if(!Tools.DrawLines(verts, BuilderPlug.Me.AutoAlignTextureOffsetsOnCreate)) //mxd
{
// Drawing failed
// NOTE: I have to call this twice, because the first time only cancels this volatile mode
General.Map.UndoRedo.WithdrawUndo();
General.Map.UndoRedo.WithdrawUndo();
return;
}
// Snap to map format accuracy
General.Map.Map.SnapAllToAccuracy();
// Clear selection
General.Map.Map.ClearAllSelected();
// Update cached values
General.Map.Map.Update();
// Edit new sectors?
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
if(BuilderPlug.Me.EditNewSector && (newsectors.Count > 0))
General.Interface.ShowEditSectors(newsectors);
// Update the used textures
General.Map.Data.UpdateUsedTextures();
// Map is changed
General.Map.IsChanged = true;
}
// Done
Cursor.Current = Cursors.Default;
// Return to original mode
General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
}
//ACTIONS
[BeginAction("increasesubdivlevel")]
protected virtual void increaseSubdivLevel() {
if(segmentLength < maxSegmentLength) {
int increment = Math.Max(minSegmentLength, segmentLength / 32 * 16);
segmentLength += increment;
if(segmentLength > maxSegmentLength)
segmentLength = maxSegmentLength;
Update();
}
}
[BeginAction("decreasesubdivlevel")]
protected virtual void decreaseSubdivLevel() {
if(segmentLength > minSegmentLength) {
int increment = Math.Max(minSegmentLength, segmentLength / 32 * 16);
segmentLength -= increment;
if(segmentLength < minSegmentLength)
segmentLength = minSegmentLength;
Update();
}
}
}
}

View file

@ -85,6 +85,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
private ToolStripMenuItem drawLinesModeMenuItem;
private ToolStripMenuItem drawRectModeMenuItem;
private ToolStripMenuItem drawEllipseModeMenuItem;
private ToolStripMenuItem drawCurveModeMenuItem;
// Settings
private int showvisualthings; // 0 = none, 1 = sprite only, 2 = sprite caged
@ -249,6 +250,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
drawRectModeMenuItem.Enabled = false;
General.Interface.AddMenu(drawRectModeMenuItem, MenuSection.ModeDrawModes);
//draw curve
drawCurveModeMenuItem = new ToolStripMenuItem("Draw Curve");
drawCurveModeMenuItem.Tag = "drawcurvemode";
drawCurveModeMenuItem.Click += new EventHandler(InvokeTaggedAction);
drawCurveModeMenuItem.Image = CodeImp.DoomBuilder.BuilderModes.Properties.Resources.DrawCurveMode;
drawCurveModeMenuItem.Enabled = false;
General.Interface.AddMenu(drawCurveModeMenuItem, MenuSection.ModeDrawModes);
//draw lines
drawLinesModeMenuItem = new ToolStripMenuItem("Draw Lines");
drawLinesModeMenuItem.Tag = "drawlinesmode";
@ -274,6 +283,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Interface.RemoveMenu(exportToObjMenuItem);
General.Interface.RemoveMenu(snapModeMenuItem);
General.Interface.RemoveMenu(drawLinesModeMenuItem);
General.Interface.RemoveMenu(drawCurveModeMenuItem);
General.Interface.RemoveMenu(drawRectModeMenuItem);
General.Interface.RemoveMenu(drawEllipseModeMenuItem);
@ -439,6 +449,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
exportToObjMenuItem.Enabled = true;
snapModeMenuItem.Enabled = true;
drawLinesModeMenuItem.Enabled = true;
drawCurveModeMenuItem.Enabled = true;
drawRectModeMenuItem.Enabled = true;
drawEllipseModeMenuItem.Enabled = true;
}
@ -454,6 +465,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
exportToObjMenuItem.Enabled = true;
snapModeMenuItem.Enabled = true;
drawLinesModeMenuItem.Enabled = true;
drawCurveModeMenuItem.Enabled = true;
drawRectModeMenuItem.Enabled = true;
drawEllipseModeMenuItem.Enabled = true;
}
@ -468,6 +480,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
exportToObjMenuItem.Enabled = false;
snapModeMenuItem.Enabled = false;
drawLinesModeMenuItem.Enabled = false;
drawCurveModeMenuItem.Enabled = false;
drawRectModeMenuItem.Enabled = false;
drawEllipseModeMenuItem.Enabled = false;
}

View file

@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.5466
// Этот код создан программой.
// Исполняемая версия:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
@ -13,12 +13,12 @@ namespace CodeImp.DoomBuilder.BuilderModes.Properties {
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
// Этот класс создан автоматически классом StronglyTypedResourceBuilder
// с помощью такого средства, как ResGen или Visual Studio.
// Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen
// с параметром /str или перестройте свой проект VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
@ -33,7 +33,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Properties {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
@ -47,8 +47,8 @@ namespace CodeImp.DoomBuilder.BuilderModes.Properties {
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
@ -116,6 +116,13 @@ namespace CodeImp.DoomBuilder.BuilderModes.Properties {
}
}
internal static System.Drawing.Bitmap DrawCurveMode {
get {
object obj = ResourceManager.GetObject("DrawCurveMode", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap DrawEllipseMode {
get {
object obj = ResourceManager.GetObject("DrawEllipseMode", resourceCulture);

View file

@ -190,4 +190,7 @@
<data name="AlignThings" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\AlignThings.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="DrawCurveMode" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DrawCurveMode.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: 3 KiB