From a1d28e1e56e06bfbde08d156e038e30cc1dcde9f Mon Sep 17 00:00:00 2001 From: volte <100103+volte@users.noreply.github.com> Date: Mon, 14 Jan 2019 13:07:08 -0500 Subject: [PATCH] Grid rotation and alignment functionality (PR#252 by Volte) --- Source/Core/Editing/GridSetup.cs | 45 +- Source/Core/Geometry/Line2D.cs | 82 ++++ Source/Core/Map/Linedef.cs | 100 ++-- Source/Core/Rendering/Plotter.cs | 22 +- Source/Core/Rendering/Renderer2D.cs | 133 ++++- Source/Core/Resources/Actions.cfg | 30 ++ Source/Core/Windows/MainForm.Designer.cs | 461 ++++++++++-------- Source/Core/Windows/MainForm.cs | 243 +++++---- .../ClassicModes/DragGeometryMode.cs | 3 +- .../ClassicModes/DrawGeometryMode.cs | 3 +- 10 files changed, 744 insertions(+), 378 deletions(-) diff --git a/Source/Core/Editing/GridSetup.cs b/Source/Core/Editing/GridSetup.cs index ff170296..31a253f8 100755 --- a/Source/Core/Editing/GridSetup.cs +++ b/Source/Core/Editing/GridSetup.cs @@ -49,6 +49,8 @@ namespace CodeImp.DoomBuilder.Editing private int gridsize; private float gridsizef; private float gridsizefinv; + private float gridrotate; + private float gridoriginx, gridoriginy; // Background private string background = ""; @@ -66,6 +68,9 @@ namespace CodeImp.DoomBuilder.Editing public int GridSize { get { return gridsize; } } //mxd public float GridSizeF { get { return gridsizef; } } + public float GridRotate { get { return gridrotate; }} + public float GridOriginX { get { return gridoriginx; }} + public float GridOriginY { get { return gridoriginy; }} internal string BackgroundName { get { return background; } } internal int BackgroundSource { get { return backsource; } } internal ImageData Background { get { return backimage; } } @@ -86,6 +91,9 @@ namespace CodeImp.DoomBuilder.Editing SetGridSize(DEFAULT_GRID_SIZE); backscalex = 1.0f; backscaley = 1.0f; + gridrotate = 0.0f; + gridoriginx = 0; + gridoriginy = 0; // Register actions General.Actions.BindMethods(this); @@ -128,6 +136,9 @@ namespace CodeImp.DoomBuilder.Editing cfg.WriteSetting(path + ".backscalex", (int)(backscalex * 100.0f)); cfg.WriteSetting(path + ".backscaley", (int)(backscaley * 100.0f)); cfg.WriteSetting(path + ".gridsize", gridsizef); + cfg.WriteSetting(path + ".gridrotate", gridrotate); + cfg.WriteSetting(path + ".gridoriginx", gridoriginx); + cfg.WriteSetting(path + ".gridoriginy", gridoriginy); } // Read settings from configuration @@ -141,6 +152,9 @@ namespace CodeImp.DoomBuilder.Editing backscalex = cfg.ReadSetting(path + ".backscalex", 100) / 100.0f; backscaley = cfg.ReadSetting(path + ".backscaley", 100) / 100.0f; gridsizef = cfg.ReadSetting(path + ".gridsize", DEFAULT_GRID_SIZE); + gridoriginx = cfg.ReadSetting(path + ".gridoriginx", 0); + gridoriginy = cfg.ReadSetting(path + ".gridoriginy", 0); + gridrotate = cfg.ReadSetting(path + ".gridrotate", 0.0f); // Setup SetGridSize(gridsizef); @@ -162,6 +176,19 @@ namespace CodeImp.DoomBuilder.Editing General.MainWindow.UpdateGrid(gridsizef); } + // Set the rotation angle of the grid + internal void SetGridRotation(float angle) + { + gridrotate = angle; + } + + // Set the origin of the grid + internal void SetGridOrigin(float x, float y) + { + gridoriginx = x; + gridoriginy = y; + } + // This sets the background internal void SetBackground(string name, int source) { @@ -226,15 +253,29 @@ namespace CodeImp.DoomBuilder.Editing // This snaps to the nearest grid coordinate public Vector2D SnappedToGrid(Vector2D v) { - return SnappedToGrid(v, gridsizef, gridsizefinv); + return SnappedToGrid(v, gridsizef, gridsizefinv, gridrotate, gridoriginx, gridoriginy); } // This snaps to the nearest grid coordinate - public static Vector2D SnappedToGrid(Vector2D v, float gridsize, float gridsizeinv) + public static Vector2D SnappedToGrid(Vector2D v, float gridsize, float gridsizeinv, float gridrotate = 0.0f, float gridoriginx = 0, float gridoriginy = 0) { + Vector2D origin = new Vector2D(gridoriginx, gridoriginy); + bool transformed = Math.Abs(gridrotate) > 1e-4 || gridoriginx != 0 || gridoriginx != 0; + if (transformed) + { + // Grid is transformed, so reverse the transformation first + v = ((v - origin).GetRotated(-gridrotate)); + } + Vector2D sv = new Vector2D((float)Math.Round(v.x * gridsizeinv) * gridsize, (float)Math.Round(v.y * gridsizeinv) * gridsize); + if (transformed) + { + // Put back into original frame + sv = sv.GetRotated(gridrotate) + origin; + } + if(sv.x < General.Map.Config.LeftBoundary) sv.x = General.Map.Config.LeftBoundary; else if(sv.x > General.Map.Config.RightBoundary) sv.x = General.Map.Config.RightBoundary; diff --git a/Source/Core/Geometry/Line2D.cs b/Source/Core/Geometry/Line2D.cs index 403868e8..d5d0d194 100755 --- a/Source/Core/Geometry/Line2D.cs +++ b/Source/Core/Geometry/Line2D.cs @@ -17,6 +17,8 @@ #region ================== Namespaces using System; +using System.Drawing; +using System.Windows.Forms; using CodeImp.DoomBuilder.Map; #endregion @@ -223,6 +225,73 @@ namespace CodeImp.DoomBuilder.Geometry // Calculate and return intersection offset return new Vector2D(v1.x + u * (v2.x - v1.x), v1.y + u * (v2.y - v1.y)); } + + // Cohen-Sutherland algorithm + public static Line2D ClipToRectangle(Line2D line, RectangleF rect, out bool intersects) + { + int flags1 = MapSet.GetCSFieldBits(line.v1, rect); + int flags2 = MapSet.GetCSFieldBits(line.v2, rect); + Line2D result = line; + intersects = false; + + // Each pass will modify one coordinate of one endpoint + for (int pass = 0; pass < 4; pass++) + { + if (flags1 == 0 && flags2 == 0) + { + // Line is fully inside the box + intersects = true; + return result; + } + + if ((flags1 & flags2) != 0) + { + // Both points are in the same outer area + return new Line2D(); + } + + float x, y; + int outFlags = flags1 != 0 ? flags1 : flags2; + if ((outFlags & 0x1) > 0) // Top + { + x = line.v1.x + (line.v2.x - line.v1.x) * (rect.Top - line.v1.y) / (line.v2.y - line.v1.y); + y = rect.Top; + } + else if ((outFlags & 0x2) > 0) // Bottom + { + x = line.v1.x + (line.v2.x - line.v1.x) * (rect.Bottom - line.v1.y) / (line.v2.y - line.v1.y); + y = rect.Bottom; + } + else if ((outFlags & 0x4) > 0) // Left + { + y = line.v1.y + (line.v2.y - line.v1.y) * (rect.Left - line.v1.x) / (line.v2.x - line.v1.x); + x = rect.Left; + } + else if ((outFlags & 0x8) > 0) // Right + { + y = line.v1.y + (line.v2.y - line.v1.y) * (rect.Right - line.v1.x) / (line.v2.x - line.v1.x); + x = rect.Right; + } + else + { + intersects = false; + return new Line2D(); + } + + if (outFlags == flags1) + { + line.v1 = new Vector2D(x, y); + flags1 = MapSet.GetCSFieldBits(line.v1, rect); + } + else + { + line.v2 = new Vector2D(x, y); + flags2 = MapSet.GetCSFieldBits(line.v2, rect); + } + } + + return line; + } #endregion @@ -318,6 +387,19 @@ namespace CodeImp.DoomBuilder.Geometry { return Line2D.GetCoordinatesAt(v1, v2, u); } + + public Line2D GetTransformed(float offsetx, float offsety, float scalex, float scaley) + { + return new Line2D(v1.GetTransformed(offsetx, offsety, scalex, scaley), + v2.GetTransformed(offsetx, offsety, scalex, scaley)); + } + + // Inverse Transform + public Line2D GetInvTransformed(float invoffsetx, float invoffsety, float invscalex, float invscaley) + { + return new Line2D(v1.GetInvTransformed(invoffsetx, invoffsety, invscalex, invscaley), + v2.GetInvTransformed(invoffsetx, invoffsety, invscalex, invscaley)); + } #endregion } diff --git a/Source/Core/Map/Linedef.cs b/Source/Core/Map/Linedef.cs index df5e3fb8..e270b65b 100755 --- a/Source/Core/Map/Linedef.cs +++ b/Source/Core/Map/Linedef.cs @@ -131,7 +131,7 @@ namespace CodeImp.DoomBuilder.Map if(map == General.Map.Map) General.Map.UndoRedo.RecAddLinedef(this); - + // We have no destructor GC.SuppressFinalize(this); } @@ -893,42 +893,58 @@ namespace CodeImp.DoomBuilder.Map } // This returns all points at which the line intersects with the grid - public List GetGridIntersections() + public List GetGridIntersections() { - return GetGridIntersections(new Vector2D()); + return GetGridIntersections(0.0f); + } + + + public List GetGridIntersections(float gridrotation, float gridoriginx = 0.0f, float gridoriginy = 0.0f) + { + return GetGridIntersections(new Vector2D(), gridrotation, gridoriginx, gridoriginy); } // This returns all points at which the line intersects with the grid - public List GetGridIntersections(Vector2D gridoffset) + public List GetGridIntersections(Vector2D gridoffset, float gridrotation = 0.0f, float gridoriginx = 0.0f, float gridoriginy = 0.0f) { List coords = new List(); Vector2D v = new Vector2D(); float minx, maxx, miny, maxy; bool reversex, reversey; - - if(start.Position.x > end.Position.x) + + Vector2D v1 = start.Position; + Vector2D v2 = end.Position; + + bool transformed = Math.Abs(gridrotation) > 1e-4 || Math.Abs(gridoriginx) > 1e-4 || Math.Abs(gridoriginy) > 1e-4; + if (transformed) { - minx = end.Position.x; - maxx = start.Position.x; + v1 = (v1 - new Vector2D(gridoriginx, gridoriginy)).GetRotated(-gridrotation); + v2 = (v2 - new Vector2D(gridoriginx, gridoriginy)).GetRotated(-gridrotation); + } + + if(v1.x > v2.x) + { + minx = v2.x; + maxx = v1.x; reversex = true; } else { - minx = start.Position.x; - maxx = end.Position.x; + minx = v1.x; + maxx = v2.x; reversex = false; } - if(start.Position.y > end.Position.y) + if(v1.y > v2.y) { - miny = end.Position.y; - maxy = start.Position.y; + miny = v2.y; + maxy = v1.y; reversey = true; } else { - miny = start.Position.y; - maxy = end.Position.y; + miny = v1.y; + maxy = v2.y; reversey = false; } @@ -942,7 +958,7 @@ namespace CodeImp.DoomBuilder.Map float u = (gx - minx) / (maxx - minx); if(reversex) u = 1.0f - u; v.x = gx; - v.y = start.Position.y + (end.Position.y - start.Position.y) * u; + v.y = v1.y + (v2.y - v1.y) * u; coords.Add(v); } } @@ -956,11 +972,19 @@ namespace CodeImp.DoomBuilder.Map // Add intersection point at this y coordinate float u = (gy - miny) / (maxy - miny); if(reversey) u = 1.0f - u; - v.x = start.Position.x + (end.Position.x - start.Position.x) * u; + v.x = v1.x + (v2.x - v1.x) * u; v.y = gy; coords.Add(v); } } + + if (transformed) + { + for (int i = 0; i < coords.Count; i++) + { + coords[i] = coords[i].GetRotated(gridrotation) + new Vector2D(gridoriginx, gridoriginy); + } + } // Profit return coords; @@ -983,34 +1007,34 @@ namespace CodeImp.DoomBuilder.Map // Calculate intersection offset float u = ((p.x - v1.x) * (v2.x - v1.x) + (p.y - v1.y) * (v2.y - v1.y)) * lengthsqinv; - // Limit intersection offset to the line - if (bounded) - { - if (General.Map.UDMF) - { - u = Math.Max(0f, Math.Min(1f, u)); - } - else // restore old way for visplane explorer (which doesn't work for UDMF anyway) - { - u = Math.Max(lengthinv, Math.Min(1f - lengthinv, u)); - } - } + // Limit intersection offset to the line + if (bounded) + { + if (General.Map.UDMF) + { + u = Math.Max(0f, Math.Min(1f, u)); + } + else // restore old way for visplane explorer (which doesn't work for UDMF anyway) + { + u = Math.Max(lengthinv, Math.Min(1f - lengthinv, u)); + } + } - /* - // Calculate intersection point - Vector2D i = v1 + u * (v2 - v1); + /* + // Calculate intersection point + Vector2D i = v1 + u * (v2 - v1); // Return distance between intersection and point // which is the shortest distance to the line float ldx = p.x - i.x; float ldy = p.y - i.y; - */ + */ - // ano - let's check to see if we can do the previous faster without using operator overloading and etc - // the answer: running it int.MaxValue / 64 times it tended to be around 100ms faster - float ldx = p.x - (v1.x + u * (v2.x - v1.x)); - float ldy = p.y - (v1.y + u * (v2.y - v1.y)); - return ldx * ldx + ldy * ldy; + // ano - let's check to see if we can do the previous faster without using operator overloading and etc + // the answer: running it int.MaxValue / 64 times it tended to be around 100ms faster + float ldx = p.x - (v1.x + u * (v2.x - v1.x)); + float ldy = p.y - (v1.y + u * (v2.y - v1.y)); + return ldx * ldx + ldy * ldy; } // This returns the shortest distance from given coordinates to line diff --git a/Source/Core/Rendering/Plotter.cs b/Source/Core/Rendering/Plotter.cs index 38e8406c..f51d7db8 100755 --- a/Source/Core/Rendering/Plotter.cs +++ b/Source/Core/Rendering/Plotter.cs @@ -209,7 +209,7 @@ namespace CodeImp.DoomBuilder.Rendering // This draws a line normally // See: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm - public void DrawLineSolid(int x1, int y1, int x2, int y2, ref PixelColor c) + public void DrawLineSolid(int x1, int y1, int x2, int y2, ref PixelColor c, uint mask = 0xffffffff) { // Check if the line is outside the screen for sure. // This is quickly done by checking in which area both points are. When this @@ -262,7 +262,9 @@ namespace CodeImp.DoomBuilder.Rendering px += sdx; // Draw pixel - pixels[py * width + px] = c; + if ((mask & (1 << (i & 0x7))) != 0) { + pixels[py * width + px] = c; + } } } // Else the line is more vertical than horizontal @@ -279,7 +281,9 @@ namespace CodeImp.DoomBuilder.Rendering py += sdy; // Draw pixel - pixels[py * width + px] = c; + if ((mask & (1 << (i & 0x7))) != 0) { + pixels[py * width + px] = c; + } } } } @@ -303,8 +307,10 @@ namespace CodeImp.DoomBuilder.Rendering px += sdx; // Draw pixel - if((px >= 0) && (px < visiblewidth) && (py >= 0) && (py < visibleheight)) - pixels[py * width + px] = c; + if ((mask & (1 << (i & 0x7))) != 0) { + if((px >= 0) && (px < visiblewidth) && (py >= 0) && (py < visibleheight)) + pixels[py * width + px] = c; + } } } // Else the line is more vertical than horizontal @@ -321,8 +327,10 @@ namespace CodeImp.DoomBuilder.Rendering py += sdy; // Draw pixel - if((px >= 0) && (px < visiblewidth) && (py >= 0) && (py < visibleheight)) - pixels[py * width + px] = c; + if ((mask & (1 << (i & 0x7))) != 0) { + if((px >= 0) && (px < visiblewidth) && (py >= 0) && (py < visibleheight)) + pixels[py * width + px] = c; + } } } } diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index fc4963b3..06742a1f 100755 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.Net; using CodeImp.DoomBuilder.Map; using SlimDX.Direct3D9; using SlimDX; @@ -28,6 +29,7 @@ using CodeImp.DoomBuilder.Editing; using CodeImp.DoomBuilder.GZBuilder.Data; //mxd using CodeImp.DoomBuilder.Config; //mxd using CodeImp.DoomBuilder.GZBuilder; +using SlimDX.Direct3D10_1; #endregion @@ -549,17 +551,17 @@ namespace CodeImp.DoomBuilder.Rendering return new PixelColor(255, 255, 255, 255); if (t.DynamicLightType.LightDef == GZGeneral.LightDef.VAVOOM_COLORED) //vavoom colored light return new PixelColor(255, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]); - if (t.DynamicLightType.LightType == GZGeneral.LightType.SPOT) - { - if (t.Fields.ContainsKey("arg0str")) - { - PixelColor pc; - ZDoom.ZDTextParser.GetColorFromString(t.Fields["arg0str"].Value.ToString(), out pc); - pc.a = 255; - return pc; - } - return new PixelColor(255, (byte)((t.Args[0] & 0xFF0000) >> 16), (byte)((t.Args[0] & 0x00FF00) >> 8), (byte)((t.Args[0] & 0x0000FF))); - } + if (t.DynamicLightType.LightType == GZGeneral.LightType.SPOT) + { + if (t.Fields.ContainsKey("arg0str")) + { + PixelColor pc; + ZDoom.ZDTextParser.GetColorFromString(t.Fields["arg0str"].Value.ToString(), out pc); + pc.a = 255; + return pc; + } + return new PixelColor(255, (byte)((t.Args[0] & 0xFF0000) >> 16), (byte)((t.Args[0] & 0x00FF00) >> 8), (byte)((t.Args[0] & 0x0000FF))); + } return new PixelColor(255, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]); } @@ -837,11 +839,30 @@ namespace CodeImp.DoomBuilder.Rendering if(General.Settings.RenderGrid) //mxd { - // Render normal grid - RenderGrid(General.Map.Grid.GridSizeF, General.Colors.Grid, gridplotter); + bool transformed = General.Map.Grid.GridOriginX != 0 || General.Map.Grid.GridOriginY != 0 || Math.Abs(General.Map.Grid.GridRotate) > 1e-4; - // Render 64 grid - if(General.Map.Grid.GridSizeF <= 64) RenderGrid(64f, General.Colors.Grid64, gridplotter); + if (transformed) + { + // Render normal grid + RenderGridTransformed(General.Map.Grid.GridSizeF, General.Map.Grid.GridRotate, + General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY, General.Colors.Grid, gridplotter); + + // Render 64 grid + if(General.Map.Grid.GridSizeF <= 64) + { + RenderGridTransformed(64f, General.Map.Grid.GridRotate, + General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY, General.Colors.Grid64, gridplotter); + } + } + else + { + // Render normal grid + RenderGrid(General.Map.Grid.GridSizeF, General.Colors.Grid, gridplotter); + + // Render 64 grid + if(General.Map.Grid.GridSizeF <= 64) RenderGrid(64f, General.Colors.Grid64, gridplotter); + } + } else { @@ -877,6 +898,88 @@ namespace CodeImp.DoomBuilder.Rendering } } + // This renders the grid with a transform applied + private void RenderGridTransformed(float size, float angle, float originx, float originy, PixelColor c, Plotter gridplotter) + { + const int mask = 0x55555555; // dotted line mask + Vector2D pos = new Vector2D(); + + //mxd. Increase rendered grid size if needed + if(!General.Settings.DynamicGridSize && size * scale <= 6f) + do { size *= 2; } while(size * scale <= 6f); + float sizeinv = 1f / size; + + if (size < 1 || size > 1024) + { + return; + } + + // Determine map coordinates for view window + Vector2D ltpos = DisplayToMap(new Vector2D(0, 0)); + Vector2D rbpos = DisplayToMap(new Vector2D(windowsize.Width, windowsize.Height)); + Vector2D mapsize = rbpos - ltpos; + + Vector2D ltbound = new Vector2D(General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary); + Vector2D rbbound = new Vector2D(General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary); + + // Translate top left boundary and right bottom boundary of map to screen coords + Vector2D tlb = ltbound.GetTransformed(translatex, translatey, scale, -scale); + Vector2D rbb = rbbound.GetTransformed(translatex, translatey, scale, -scale); + + Vector2D xcenter = GridSetup.SnappedToGrid(0.5f * (ltpos + rbpos), size, sizeinv, angle, originx, originy); + Vector2D ycenter = xcenter; + + // Get the angle vectors for the gridlines + Vector2D dx = new Vector2D((float)Math.Cos(angle), (float)Math.Sin(angle)); + Vector2D dy = new Vector2D((float)-Math.Sin(angle), (float)Math.Cos(angle)); + + float maxextent = Math.Max(mapsize.x, mapsize.y); + RectangleF bounds = new RectangleF(tlb.x, tlb.y, rbb.x - tlb.x, rbb.y - tlb.y); + + bool xminintersect = true, xmaxintersect = true, yminintersect = true, ymaxintersect = true; + + int num = 0; + while (xminintersect || xmaxintersect || yminintersect || ymaxintersect) { + Vector2D xminstart = xcenter - num * size * dy; + Vector2D xmaxstart = xcenter + num * size * dy; + Vector2D yminstart = ycenter - num * size * dx; + Vector2D ymaxstart = ycenter + num * size * dx; + + Line2D xminscanline = new Line2D(xminstart - dx * maxextent, xminstart + dx * maxextent); + Line2D xmaxscanline = new Line2D(xmaxstart - dx * maxextent, xmaxstart + dx * maxextent); + Line2D yminscanline = new Line2D(yminstart - dy * maxextent, yminstart + dy * maxextent); + Line2D ymaxscanline = new Line2D(ymaxstart - dy * maxextent, ymaxstart + dy * maxextent); + + Line2D xminplotline = xminscanline.GetTransformed(translatex, translatey, scale, -scale); + Line2D xmaxplotline = xmaxscanline.GetTransformed(translatex, translatey, scale, -scale); + Line2D yminplotline = yminscanline.GetTransformed(translatex, translatey, scale, -scale); + Line2D ymaxplotline = ymaxscanline.GetTransformed(translatex, translatey, scale, -scale); + xminplotline = Line2D.ClipToRectangle(xminplotline, bounds, out xminintersect); + xmaxplotline = Line2D.ClipToRectangle(xmaxplotline, bounds, out xmaxintersect); + yminplotline = Line2D.ClipToRectangle(yminplotline, bounds, out yminintersect); + ymaxplotline = Line2D.ClipToRectangle(ymaxplotline, bounds, out ymaxintersect); + + if (xminintersect) + { + gridplotter.DrawLineSolid((int)xminplotline.v1.x, (int)xminplotline.v1.y, (int)xminplotline.v2.x, (int)xminplotline.v2.y, ref c, mask); + } + if (xmaxintersect) + { + gridplotter.DrawLineSolid((int)xmaxplotline.v1.x, (int)xmaxplotline.v1.y, (int)xmaxplotline.v2.x, (int)xmaxplotline.v2.y, ref c, mask); + } + if (yminintersect) + { + gridplotter.DrawLineSolid((int)yminplotline.v1.x, (int)yminplotline.v1.y, (int)yminplotline.v2.x, (int)yminplotline.v2.y, ref c, mask); + } + if (ymaxintersect) + { + gridplotter.DrawLineSolid((int)ymaxplotline.v1.x, (int)ymaxplotline.v1.y, (int)ymaxplotline.v2.x, (int)ymaxplotline.v2.y, ref c, mask); + } + + num++; + } + } + // This renders the grid private void RenderGrid(float size, PixelColor c, Plotter gridplotter) { diff --git a/Source/Core/Resources/Actions.cfg b/Source/Core/Resources/Actions.cfg index e66d169a..22191cf6 100755 --- a/Source/Core/Resources/Actions.cfg +++ b/Source/Core/Resources/Actions.cfg @@ -416,6 +416,36 @@ gridsetup allowscroll = true; } +aligngridtolinedef +{ + title = "Align Grid to Selected Linedef"; + category = "classic"; + description = "Realigns the grid so that the selected linedef is on a grid line."; + allowkeys = true; + allowmouse = false; + allowscroll = false; +} + +setgridorigintovertex +{ + title = "Set Grid Origin to Selected Vertex"; + category = "classic"; + description = "Repositions the grid so that the selected vertex is at the origin."; + allowkeys = true; + allowmouse = false; + allowscroll = false; +} + +resetgrid +{ + title = "Reset Grid Transform"; + category = "classic"; + description = "Resets the grid to the default coordinate system."; + allowkeys = true; + allowmouse = false; + allowscroll = false; +} + griddec // Note, these were incorrectly swapped before, hence the wrong action name { title = "Grid Increase"; diff --git a/Source/Core/Windows/MainForm.Designer.cs b/Source/Core/Windows/MainForm.Designer.cs index 84a3f4ab..554ab8d3 100755 --- a/Source/Core/Windows/MainForm.Designer.cs +++ b/Source/Core/Windows/MainForm.Designer.cs @@ -287,6 +287,9 @@ namespace CodeImp.DoomBuilder.Windows this.itemtogglecomments = new System.Windows.Forms.ToolStripMenuItem(); this.itemtogglefixedthingsscale = new System.Windows.Forms.ToolStripMenuItem(); this.itemdynamicgridsize = new System.Windows.Forms.ToolStripMenuItem(); + this.itemaligngridtolinedef = new System.Windows.Forms.ToolStripMenuItem(); + this.itemsetgridorigintovertex = new System.Windows.Forms.ToolStripMenuItem(); + this.itemresetgrid = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator(); toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator(); @@ -402,13 +405,13 @@ namespace CodeImp.DoomBuilder.Windows // this.menumain.Dock = System.Windows.Forms.DockStyle.None; this.menumain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.menufile, - this.menuedit, - this.menuview, - this.menumode, - this.menuprefabs, - this.menutools, - this.menuhelp}); + this.menufile, + this.menuedit, + this.menuview, + this.menumode, + this.menuprefabs, + this.menutools, + this.menuhelp}); this.menumain.Location = new System.Drawing.Point(0, 0); this.menumain.Name = "menumain"; this.menumain.Size = new System.Drawing.Size(328, 24); @@ -418,21 +421,21 @@ namespace CodeImp.DoomBuilder.Windows // menufile // this.menufile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemnewmap, - this.itemopenmap, - this.itemopenmapincurwad, - this.itemclosemap, - this.seperatorfileopen, - this.itemsavemap, - this.itemsavemapas, - this.itemsavemapinto, - this.seperatorfilesave, - this.itemimport, - this.itemexport, - this.separatorio, - this.itemnorecent, - this.seperatorfilerecent, - this.itemexit}); + this.itemnewmap, + this.itemopenmap, + this.itemopenmapincurwad, + this.itemclosemap, + this.seperatorfileopen, + this.itemsavemap, + this.itemsavemapas, + this.itemsavemapinto, + this.seperatorfilesave, + this.itemimport, + this.itemexport, + this.separatorio, + this.itemnorecent, + this.seperatorfilerecent, + this.itemexit}); this.menufile.Name = "menufile"; this.menufile.Size = new System.Drawing.Size(37, 20); this.menufile.Text = "&File"; @@ -538,36 +541,39 @@ namespace CodeImp.DoomBuilder.Windows // menuedit // this.menuedit.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemundo, - this.itemredo, - this.seperatoreditundo, - this.itemcut, - this.itemcopy, - this.itempaste, - this.itempastespecial, - this.seperatoreditcopypaste, + this.itemundo, + this.itemredo, + this.seperatoreditundo, + this.itemcut, + this.itemcopy, + this.itempaste, + this.itempastespecial, + this.seperatoreditcopypaste, this.itemmergegeoclassic, this.itemmergegeo, this.itemreplacegeo, this.separatorgeomerge, - this.itemsnaptogrid, - this.itemdynamicgridsize, - this.itemautomerge, + this.itemsnaptogrid, + this.itemdynamicgridsize, + this.itemautomerge, this.itemsplitjoinedsectors, - this.itemautoclearsidetextures, - this.seperatoreditgeometry, - this.itemgridinc, - this.itemgriddec, - this.itemdosnaptogrid, - this.itemgridsetup, - this.toolStripSeparator5, - this.addToGroup, - this.selectGroup, - this.clearGroup, - this.seperatoreditgrid, - this.itemmapoptions, - this.itemviewusedtags, - this.itemviewthingtypes}); + this.itemautoclearsidetextures, + this.seperatoreditgeometry, + this.itemgridinc, + this.itemgriddec, + this.itemdosnaptogrid, + this.itemaligngridtolinedef, + this.itemsetgridorigintovertex, + this.itemresetgrid, + this.itemgridsetup, + this.toolStripSeparator5, + this.addToGroup, + this.selectGroup, + this.clearGroup, + this.seperatoreditgrid, + this.itemmapoptions, + this.itemviewusedtags, + this.itemviewthingtypes}); this.menuedit.Name = "menuedit"; this.menuedit.Size = new System.Drawing.Size(39, 20); this.menuedit.Text = "&Edit"; @@ -775,32 +781,32 @@ namespace CodeImp.DoomBuilder.Windows // menuview // this.menuview.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemthingsfilter, - this.itemlinedefcolors, - this.seperatorviewthings, - this.itemviewnormal, - this.itemviewbrightness, - this.itemviewfloors, - this.itemviewceilings, - this.seperatorviewviews, - this.itemfullbrightness, - this.itemtogglegrid, - this.itemtogglecomments, + this.itemthingsfilter, + this.itemlinedefcolors, + this.seperatorviewthings, + this.itemviewnormal, + this.itemviewbrightness, + this.itemviewfloors, + this.itemviewceilings, + this.seperatorviewviews, + this.itemfullbrightness, + this.itemtogglegrid, + this.itemtogglecomments, this.itemtogglefixedthingsscale, this.separatorrendering, - this.itemdynlightmodes, - this.itemmodelmodes, - this.itemtogglefog, - this.itemtogglesky, - this.itemtoggleeventlines, - this.itemtogglevisualverts, - this.separatorhelpers, - this.menuzoom, - this.itemgotocoords, - this.itemfittoscreen, - this.itemtoggleinfo, - this.seperatorviewzoom, - this.itemscripteditor}); + this.itemdynlightmodes, + this.itemmodelmodes, + this.itemtogglefog, + this.itemtogglesky, + this.itemtoggleeventlines, + this.itemtogglevisualverts, + this.separatorhelpers, + this.menuzoom, + this.itemgotocoords, + this.itemfittoscreen, + this.itemtoggleinfo, + this.seperatorviewzoom, + this.itemscripteditor}); this.menuview.Name = "menuview"; this.menuview.Size = new System.Drawing.Size(44, 20); this.menuview.Text = "&View"; @@ -925,6 +931,34 @@ namespace CodeImp.DoomBuilder.Windows this.itemtogglegrid.Tag = "builder_togglegrid"; this.itemtogglegrid.Text = "&Render Grid"; this.itemtogglegrid.Click += new System.EventHandler(this.InvokeTaggedAction); + + // + // itemaligngridtolinedef + // + this.itemaligngridtolinedef.Name = "itemaligngridtolinedef"; + this.itemaligngridtolinedef.Size = new System.Drawing.Size(215, 22); + this.itemaligngridtolinedef.Tag = "builder_aligngridtolinedef"; + this.itemaligngridtolinedef.Text = "Align Grid To Selected Linedef"; + this.itemaligngridtolinedef.Click += new System.EventHandler(this.InvokeTaggedAction); + + // + // itemsetgridorigintovertex + // + this.itemsetgridorigintovertex.Name = "itemsetgridorigintovertex"; + this.itemsetgridorigintovertex.Size = new System.Drawing.Size(215, 22); + this.itemsetgridorigintovertex.Tag = "builder_setgridorigintovertex"; + this.itemsetgridorigintovertex.Text = "Set Grid Origin To Selected Vertex"; + this.itemsetgridorigintovertex.Click += new System.EventHandler(this.InvokeTaggedAction); + + // + // itemresetgrid + // + this.itemresetgrid.Name = "itemresetgrid"; + this.itemresetgrid.Size = new System.Drawing.Size(215, 22); + this.itemresetgrid.Tag = "builder_resetgrid"; + this.itemresetgrid.Text = "Reset Grid Transform"; + this.itemresetgrid.Click += new System.EventHandler(this.InvokeTaggedAction); + // // toolStripSeparator4 // @@ -934,14 +968,14 @@ namespace CodeImp.DoomBuilder.Windows // menuzoom // this.menuzoom.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.item2zoom800, - this.item2zoom400, - this.item2zoom200, - this.item2zoom100, - this.item2zoom50, - this.item2zoom25, - this.item2zoom10, - this.item2zoom5}); + this.item2zoom800, + this.item2zoom400, + this.item2zoom200, + this.item2zoom100, + this.item2zoom50, + this.item2zoom25, + this.item2zoom10, + this.item2zoom5}); this.menuzoom.Image = global::CodeImp.DoomBuilder.Properties.Resources.Zoom; this.menuzoom.Name = "menuzoom"; this.menuzoom.Size = new System.Drawing.Size(215, 22); @@ -1053,8 +1087,8 @@ namespace CodeImp.DoomBuilder.Windows // menumode // this.menumode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.separatorDrawModes, - this.separatorTransformModes}); + this.separatorDrawModes, + this.separatorTransformModes}); this.menumode.Name = "menumode"; this.menumode.Size = new System.Drawing.Size(50, 20); this.menumode.Text = "&Mode"; @@ -1072,10 +1106,10 @@ namespace CodeImp.DoomBuilder.Windows // menuprefabs // this.menuprefabs.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.iteminsertprefabfile, - this.iteminsertpreviousprefab, - this.seperatorprefabsinsert, - this.itemcreateprefab}); + this.iteminsertprefabfile, + this.iteminsertpreviousprefab, + this.seperatorprefabsinsert, + this.itemcreateprefab}); this.menuprefabs.Name = "menuprefabs"; this.menuprefabs.Size = new System.Drawing.Size(58, 20); this.menuprefabs.Text = "&Prefabs"; @@ -1115,18 +1149,18 @@ namespace CodeImp.DoomBuilder.Windows // menutools // this.menutools.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemreloadresources, - this.itemReloadModedef, - this.itemReloadGldefs, - this.itemshowerrors, - this.seperatortoolsresources, - this.configurationToolStripMenuItem, - this.preferencesToolStripMenuItem, - this.seperatortoolsconfig, - this.itemsavescreenshot, - this.itemsaveeditareascreenshot, - this.separatortoolsscreenshots, - this.itemtestmap}); + this.itemreloadresources, + this.itemReloadModedef, + this.itemReloadGldefs, + this.itemshowerrors, + this.seperatortoolsresources, + this.configurationToolStripMenuItem, + this.preferencesToolStripMenuItem, + this.seperatortoolsconfig, + this.itemsavescreenshot, + this.itemsaveeditareascreenshot, + this.separatortoolsscreenshots, + this.itemtestmap}); this.menutools.Name = "menutools"; this.menutools.Size = new System.Drawing.Size(48, 20); this.menutools.Text = "&Tools"; @@ -1232,14 +1266,14 @@ namespace CodeImp.DoomBuilder.Windows // menuhelp // this.menuhelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemhelprefmanual, - this.itemShortcutReference, + this.itemhelprefmanual, + this.itemShortcutReference, this.itemopenconfigfolder, - this.itemhelpeditmode, + this.itemhelpeditmode, this.itemhelpissues, - this.itemhelpcheckupdates, - this.seperatorhelpmanual, - this.itemhelpabout}); + this.itemhelpcheckupdates, + this.seperatorhelpmanual, + this.itemhelpabout}); this.menuhelp.Name = "menuhelp"; this.menuhelp.Size = new System.Drawing.Size(44, 20); this.menuhelp.Text = "&Help"; @@ -1315,57 +1349,57 @@ namespace CodeImp.DoomBuilder.Windows this.toolbar.ContextMenuStrip = this.toolbarContextMenu; this.toolbar.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.toolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.buttonnewmap, - this.buttonopenmap, - this.buttonsavemap, - this.seperatorfile, - this.buttonscripteditor, - this.seperatorscript, - this.buttonundo, - this.buttonredo, - this.seperatorundo, - this.buttoncut, - this.buttoncopy, - this.buttonpaste, - this.seperatorcopypaste, - this.buttoninsertprefabfile, - this.buttoninsertpreviousprefab, - this.seperatorprefabs, - this.buttonthingsfilter, - this.thingfilters, - this.separatorlinecolors, - this.buttonlinededfcolors, - this.linedefcolorpresets, - this.separatorfilters, - this.buttonfullbrightness, - this.buttontogglegrid, - this.buttontogglecomments, + this.buttonnewmap, + this.buttonopenmap, + this.buttonsavemap, + this.seperatorfile, + this.buttonscripteditor, + this.seperatorscript, + this.buttonundo, + this.buttonredo, + this.seperatorundo, + this.buttoncut, + this.buttoncopy, + this.buttonpaste, + this.seperatorcopypaste, + this.buttoninsertprefabfile, + this.buttoninsertpreviousprefab, + this.seperatorprefabs, + this.buttonthingsfilter, + this.thingfilters, + this.separatorlinecolors, + this.buttonlinededfcolors, + this.linedefcolorpresets, + this.separatorfilters, + this.buttonfullbrightness, + this.buttontogglegrid, + this.buttontogglecomments, this.buttontogglefixedthingsscale, - this.separatorfullbrightness, - this.buttonviewnormal, - this.buttonviewbrightness, - this.buttonviewfloors, - this.buttonviewceilings, + this.separatorfullbrightness, + this.buttonviewnormal, + this.buttonviewbrightness, + this.buttonviewfloors, + this.buttonviewceilings, this.separatorgeomergemodes, this.buttonmergegeoclassic, this.buttonmergegeo, this.buttonplacegeo, - this.seperatorviews, - this.buttonsnaptogrid, - this.buttontoggledynamicgrid, - this.buttonautomerge, + this.seperatorviews, + this.buttonsnaptogrid, + this.buttontoggledynamicgrid, + this.buttonautomerge, this.buttonsplitjoinedsectors, - this.buttonautoclearsidetextures, - this.seperatorgeometry, - this.dynamiclightmode, - this.modelrendermode, - this.buttontogglefog, + this.buttonautoclearsidetextures, + this.seperatorgeometry, + this.dynamiclightmode, + this.modelrendermode, + this.buttontogglefog, this.buttontogglesky, - this.buttontoggleeventlines, - this.buttontogglevisualvertices, - this.separatorgzmodes, - this.buttontest, - this.seperatortesting}); + this.buttontoggleeventlines, + this.buttontogglevisualvertices, + this.separatorgzmodes, + this.buttontest, + this.seperatortesting}); this.toolbar.Location = new System.Drawing.Point(0, 24); this.toolbar.Name = "toolbar"; this.toolbar.Size = new System.Drawing.Size(1012, 25); @@ -1374,16 +1408,16 @@ namespace CodeImp.DoomBuilder.Windows // toolbarContextMenu // this.toolbarContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toggleFile, - this.toggleScript, - this.toggleUndo, - this.toggleCopy, - this.togglePrefabs, - this.toggleFilter, - this.toggleViewModes, - this.toggleGeometry, - this.toggleTesting, - this.toggleRendering}); + this.toggleFile, + this.toggleScript, + this.toggleUndo, + this.toggleCopy, + this.togglePrefabs, + this.toggleFilter, + this.toggleViewModes, + this.toggleGeometry, + this.toggleTesting, + this.toggleRendering}); this.toolbarContextMenu.Name = "toolbarContextMenu"; this.toolbarContextMenu.Size = new System.Drawing.Size(227, 224); this.toolbarContextMenu.ImageScalingSize = MainForm.ScaledIconSize; @@ -1653,9 +1687,9 @@ namespace CodeImp.DoomBuilder.Windows // itemdynlightmodes // this.itemdynlightmodes.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemnodynlights, - this.itemdynlights, - this.itemdynlightsanim}); + this.itemnodynlights, + this.itemdynlights, + this.itemdynlightsanim}); this.itemdynlightmodes.Image = global::CodeImp.DoomBuilder.Properties.Resources.Light; this.itemdynlightmodes.Name = "itemdynlightmodes"; this.itemdynlightmodes.Size = new System.Drawing.Size(273, 22); @@ -1694,10 +1728,10 @@ namespace CodeImp.DoomBuilder.Windows // itemmodelmodes // this.itemmodelmodes.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemnomdl, - this.itemselmdl, - this.itemfiltermdl, - this.itemallmdl}); + this.itemnomdl, + this.itemselmdl, + this.itemfiltermdl, + this.itemallmdl}); this.itemmodelmodes.Image = global::CodeImp.DoomBuilder.Properties.Resources.Model; this.itemmodelmodes.Name = "itemmodelmodes"; this.itemmodelmodes.Size = new System.Drawing.Size(273, 22); @@ -2015,9 +2049,9 @@ namespace CodeImp.DoomBuilder.Windows // this.dynamiclightmode.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.dynamiclightmode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.sightsdontshow, - this.lightsshow, - this.lightsshowanimated}); + this.sightsdontshow, + this.lightsshow, + this.lightsshowanimated}); this.dynamiclightmode.Image = global::CodeImp.DoomBuilder.Properties.Resources.Light; this.dynamiclightmode.ImageTransparentColor = System.Drawing.Color.Magenta; this.dynamiclightmode.Name = "dynamiclightmode"; @@ -2060,10 +2094,10 @@ namespace CodeImp.DoomBuilder.Windows // this.modelrendermode.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.modelrendermode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.modelsdontshow, - this.modelsshowselection, - this.modelsshowfiltered, - this.modelsshowall}); + this.modelsdontshow, + this.modelsshowselection, + this.modelsshowfiltered, + this.modelsshowall}); this.modelrendermode.Image = global::CodeImp.DoomBuilder.Properties.Resources.Model; this.modelrendermode.ImageTransparentColor = System.Drawing.Color.Magenta; this.modelrendermode.Name = "modelrendermode"; @@ -2185,20 +2219,20 @@ 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.configlabel, - toolStripSeparator12, - this.gridlabel, - this.buttongrid, - toolStripSeparator1, - this.zoomlabel, - this.buttonzoom, - toolStripSeparator3, - this.xposlabel, - this.poscommalabel, - this.yposlabel, - toolStripSeparator9, - this.warnsLabel}); + this.statuslabel, + this.configlabel, + toolStripSeparator12, + this.gridlabel, + this.buttongrid, + toolStripSeparator1, + this.zoomlabel, + this.buttonzoom, + toolStripSeparator3, + this.xposlabel, + this.poscommalabel, + this.yposlabel, + toolStripSeparator9, + this.warnsLabel}); this.statusbar.Location = new System.Drawing.Point(0, 670); this.statusbar.Name = "statusbar"; this.statusbar.ShowItemToolTips = true; @@ -2243,21 +2277,21 @@ namespace CodeImp.DoomBuilder.Windows this.buttongrid.AutoToolTip = false; this.buttongrid.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.buttongrid.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemgrid1024, - this.itemgrid512, - this.itemgrid256, - this.itemgrid128, - this.itemgrid64, - this.itemgrid32, - this.itemgrid16, - this.itemgrid8, - this.itemgrid4, - this.itemgrid1, - this.itemgrid05, - this.itemgrid025, - this.itemgrid0125, - toolStripMenuItem4, - this.itemgridcustom}); + this.itemgrid1024, + this.itemgrid512, + this.itemgrid256, + this.itemgrid128, + this.itemgrid64, + this.itemgrid32, + this.itemgrid16, + this.itemgrid8, + this.itemgrid4, + this.itemgrid1, + this.itemgrid05, + this.itemgrid025, + this.itemgrid0125, + toolStripMenuItem4, + this.itemgridcustom}); this.buttongrid.Image = global::CodeImp.DoomBuilder.Properties.Resources.Grid2_arrowup; this.buttongrid.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.buttongrid.ImageTransparentColor = System.Drawing.Color.Transparent; @@ -2393,16 +2427,16 @@ namespace CodeImp.DoomBuilder.Windows this.buttonzoom.AutoToolTip = false; this.buttonzoom.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.buttonzoom.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.itemzoom800, - this.itemzoom400, - this.itemzoom200, - this.itemzoom100, - this.itemzoom50, - this.itemzoom25, - this.itemzoom10, - this.itemzoom5, - toolStripSeparator2, - this.itemzoomfittoscreen}); + this.itemzoom800, + this.itemzoom400, + this.itemzoom200, + this.itemzoom100, + this.itemzoom50, + this.itemzoom25, + this.itemzoom10, + this.itemzoom5, + toolStripSeparator2, + this.itemzoomfittoscreen}); this.buttonzoom.Image = global::CodeImp.DoomBuilder.Properties.Resources.Zoom_arrowup; this.buttonzoom.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.buttonzoom.ImageTransparentColor = System.Drawing.Color.Transparent; @@ -2800,8 +2834,8 @@ namespace CodeImp.DoomBuilder.Windows this.MainMenuStrip = this.menumain; this.Name = "MainForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; - this.Text = Application.ProductName + " R" + General.ThisAssembly.GetName().Version.Revision; - this.Deactivate += new System.EventHandler(this.MainForm_Deactivate); + this.Text = Application.ProductName + " R" + General.ThisAssembly.GetName().Version.Revision; + this.Deactivate += new System.EventHandler(this.MainForm_Deactivate); this.Load += new System.EventHandler(this.MainForm_Load); this.Shown += new System.EventHandler(this.MainForm_Shown); this.Activated += new System.EventHandler(this.MainForm_Activated); @@ -3066,6 +3100,9 @@ namespace CodeImp.DoomBuilder.Windows private ToolStripDropDownButton linedefcolorpresets; private ToolStripDropDownButton thingfilters; private ToolStripMenuItem itemtogglegrid; + private ToolStripMenuItem itemaligngridtolinedef; + private ToolStripMenuItem itemsetgridorigintovertex; + private ToolStripMenuItem itemresetgrid; private ToolStripButton buttontogglegrid; private ToolStripButton buttontoggledynamicgrid; private ToolStripMenuItem itemdynamicgridsize; diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index d9f04220..0141d2c9 100755 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -439,12 +439,12 @@ namespace CodeImp.DoomBuilder.Windows //mxd private void UpdateTitle() { - string programname = this.Text = Application.ProductName + " R" + General.ThisAssembly.GetName().Version.Revision; - if (Environment.Is64BitProcess) - programname += " (64-bit)"; + string programname = this.Text = Application.ProductName + " R" + General.ThisAssembly.GetName().Version.Revision; + if (Environment.Is64BitProcess) + programname += " (64-bit)"; - // Map opened? - if (General.Map != null) + // Map opened? + if (General.Map != null) { // Get nice name string maptitle = (!string.IsNullOrEmpty(General.Map.Data.MapInfo.Title) ? ": " + General.Map.Data.MapInfo.Title : ""); @@ -454,9 +454,9 @@ namespace CodeImp.DoomBuilder.Windows } else { - // Show normal caption - this.Text = programname; - } + // Show normal caption + this.Text = programname; + } } // Generic event that invokes the tagged action @@ -1364,28 +1364,28 @@ namespace CodeImp.DoomBuilder.Windows base.OnMouseWheel(e); } - // [ZZ] - private void OnMouseHWheel(int delta) - { - int mod = 0; - if (alt) mod |= (int)Keys.Alt; - if (shift) mod |= (int)Keys.Shift; - if (ctrl) mod |= (int)Keys.Control; + // [ZZ] + private void OnMouseHWheel(int delta) + { + int mod = 0; + if (alt) mod |= (int)Keys.Alt; + if (shift) mod |= (int)Keys.Shift; + if (ctrl) mod |= (int)Keys.Control; - // Scrollwheel left? - if (delta < 0) - { - General.Actions.KeyPressed((int)SpecialKeys.MScrollLeft | mod); - General.Actions.KeyReleased((int)SpecialKeys.MScrollLeft | mod); - } - else if (delta > 0) - { - General.Actions.KeyPressed((int)SpecialKeys.MScrollRight | mod); - General.Actions.KeyReleased((int)SpecialKeys.MScrollRight | mod); - } + // Scrollwheel left? + if (delta < 0) + { + General.Actions.KeyPressed((int)SpecialKeys.MScrollLeft | mod); + General.Actions.KeyReleased((int)SpecialKeys.MScrollLeft | mod); + } + else if (delta > 0) + { + General.Actions.KeyPressed((int)SpecialKeys.MScrollRight | mod); + General.Actions.KeyReleased((int)SpecialKeys.MScrollRight | mod); + } - // base? what base? - } + // base? what base? + } // When a key is pressed private void MainForm_KeyDown(object sender, KeyEventArgs e) @@ -2140,12 +2140,12 @@ namespace CodeImp.DoomBuilder.Windows // This checks one of the edit mode items (and unchecks all others) internal void CheckEditModeButton(string modeclassname) { - // Go for all items - //foreach(ToolStripItem item in editmodeitems) - int itemCount = editmodeitems.Count; - for(int i = 0; i < itemCount; i++) + // Go for all items + //foreach(ToolStripItem item in editmodeitems) + int itemCount = editmodeitems.Count; + for(int i = 0; i < itemCount; i++) { - ToolStripItem item = editmodeitems[i]; + ToolStripItem item = editmodeitems[i]; // Check what type it is if(item is ToolStripMenuItem) { @@ -2163,14 +2163,14 @@ namespace CodeImp.DoomBuilder.Windows // This removes the config-specific editing mode buttons internal void RemoveEditModeButtons() { - // Go for all items - //foreach(ToolStripItem item in editmodeitems) - int itemCount = editmodeitems.Count; - for (int i = 0; i < itemCount; i++) - { - ToolStripItem item = editmodeitems[i]; - // Remove it and restart - menumode.DropDownItems.Remove(item); + // Go for all items + //foreach(ToolStripItem item in editmodeitems) + int itemCount = editmodeitems.Count; + for (int i = 0; i < itemCount; i++) + { + ToolStripItem item = editmodeitems[i]; + // Remove it and restart + menumode.DropDownItems.Remove(item); item.Dispose(); } @@ -2911,6 +2911,45 @@ namespace CodeImp.DoomBuilder.Windows General.Map.CRenderer2D.GridVisibilityChanged(); General.Interface.RedrawDisplay(); } + + [BeginAction("aligngridtolinedef")] + protected void AlignGridToLinedef() + { + if (General.Map.Map.SelectedLinedefsCount != 1) + { + General.ShowErrorMessage("Exactly one linedef must be selected.", MessageBoxButtons.OK); + return; + } + Linedef line = General.Map.Map.SelectedLinedefs.First.Value; + Vertex vertex = line.Start; + General.Map.Grid.SetGridRotation(line.Angle); + General.Map.Grid.SetGridOrigin(vertex.Position.x, vertex.Position.y); + General.Map.CRenderer2D.GridVisibilityChanged(); + General.Interface.RedrawDisplay(); + } + + [BeginAction("setgridorigintovertex")] + protected void SetGridOriginToVertex() + { + if (General.Map.Map.SelectedVerticessCount != 1) + { + General.ShowErrorMessage("Exactly one vertex must be selected.", MessageBoxButtons.OK); + return; + } + Vertex vertex = General.Map.Map.SelectedVertices.First.Value; + General.Map.Grid.SetGridOrigin(vertex.Position.x, vertex.Position.y); + General.Map.CRenderer2D.GridVisibilityChanged(); + General.Interface.RedrawDisplay(); + } + + [BeginAction("resetgrid")] + protected void ResetGrid() + { + General.Map.Grid.SetGridRotation(0.0f); + General.Map.Grid.SetGridOrigin(0, 0); + General.Map.CRenderer2D.GridVisibilityChanged(); + General.Interface.RedrawDisplay(); + } //mxd [BeginAction("toggledynamicgrid")] @@ -3657,9 +3696,9 @@ namespace CodeImp.DoomBuilder.Windows // This hides all info panels public void HideInfo() { - // Hide them all - // [ZZ] - panelinfo.SuspendLayout(); + // Hide them all + // [ZZ] + panelinfo.SuspendLayout(); bool showModeName = ((General.Map != null) && IsInfoPanelExpanded); //mxd lastinfoobject = null; if(linedefinfo.Visible) linedefinfo.Hide(); @@ -3678,8 +3717,8 @@ namespace CodeImp.DoomBuilder.Windows //mxd. Let the plugins know General.Plugins.OnHighlightLost(); - // [ZZ] - panelinfo.ResumeLayout(); + // [ZZ] + panelinfo.ResumeLayout(); } // This refreshes info @@ -3690,11 +3729,11 @@ namespace CodeImp.DoomBuilder.Windows else if(lastinfoobject is Sector) ShowSectorInfo((Sector)lastinfoobject); else if(lastinfoobject is Thing) ShowThingInfo((Thing)lastinfoobject); - //mxd. Let the plugins know - // [ZZ] - panelinfo.SuspendLayout(); + //mxd. Let the plugins know + // [ZZ] + panelinfo.SuspendLayout(); General.Plugins.OnHighlightRefreshed(lastinfoobject); - panelinfo.ResumeLayout(); + panelinfo.ResumeLayout(); } //mxd @@ -3743,9 +3782,9 @@ namespace CodeImp.DoomBuilder.Windows return; } - // [ZZ] - panelinfo.SuspendLayout(); - lastinfoobject = l; + // [ZZ] + panelinfo.SuspendLayout(); + lastinfoobject = l; modename.Visible = false; #if DEBUG console.Visible = console.AlwaysOnTop; //mxd @@ -3772,11 +3811,11 @@ namespace CodeImp.DoomBuilder.Windows } labelcollapsedinfo.Refresh(); - //mxd. let the plugins know - General.Plugins.OnHighlightLinedef(l); - // [ZZ] - panelinfo.ResumeLayout(); - } + //mxd. let the plugins know + General.Plugins.OnHighlightLinedef(l); + // [ZZ] + panelinfo.ResumeLayout(); + } // Show vertex info public void ShowVertexInfo(Vertex v) @@ -3786,10 +3825,10 @@ namespace CodeImp.DoomBuilder.Windows HideInfo(); return; } - - // [ZZ] - panelinfo.SuspendLayout(); - lastinfoobject = v; + + // [ZZ] + panelinfo.SuspendLayout(); + lastinfoobject = v; modename.Visible = false; #if DEBUG console.Visible = console.AlwaysOnTop; //mxd @@ -3806,12 +3845,12 @@ namespace CodeImp.DoomBuilder.Windows //mxd. let the plugins know General.Plugins.OnHighlightVertex(v); - // [ZZ] - panelinfo.ResumeLayout(); - } + // [ZZ] + panelinfo.ResumeLayout(); + } - //mxd. Show sector info - public void ShowSectorInfo(Sector s) + //mxd. Show sector info + public void ShowSectorInfo(Sector s) { ShowSectorInfo(s, false, false); } @@ -3825,9 +3864,9 @@ namespace CodeImp.DoomBuilder.Windows return; } - // [ZZ] - panelinfo.SuspendLayout(); - lastinfoobject = s; + // [ZZ] + panelinfo.SuspendLayout(); + lastinfoobject = s; modename.Visible = false; #if DEBUG console.Visible = console.AlwaysOnTop; //mxd @@ -3848,14 +3887,14 @@ namespace CodeImp.DoomBuilder.Windows labelcollapsedinfo.Refresh(); - //mxd. let the plugins know - General.Plugins.OnHighlightSector(s); - // [ZZ] - panelinfo.ResumeLayout(); - } + //mxd. let the plugins know + General.Plugins.OnHighlightSector(s); + // [ZZ] + panelinfo.ResumeLayout(); + } - // Show thing info - public void ShowThingInfo(Thing t) + // Show thing info + public void ShowThingInfo(Thing t) { if(t.IsDisposed) { @@ -3863,9 +3902,9 @@ namespace CodeImp.DoomBuilder.Windows return; } - // [ZZ] - panelinfo.SuspendLayout(); - lastinfoobject = t; + // [ZZ] + panelinfo.SuspendLayout(); + lastinfoobject = t; modename.Visible = false; #if DEBUG console.Visible = console.AlwaysOnTop; //mxd @@ -3881,19 +3920,19 @@ namespace CodeImp.DoomBuilder.Windows labelcollapsedinfo.Text = t.Type + " - " + ti.Title; labelcollapsedinfo.Refresh(); - //mxd. let the plugins know - General.Plugins.OnHighlightThing(t); - // [ZZ] - panelinfo.ResumeLayout(); - } + //mxd. let the plugins know + General.Plugins.OnHighlightThing(t); + // [ZZ] + panelinfo.ResumeLayout(); + } - #endregion + #endregion - #region ================== Dialogs + #region ================== Dialogs - // This browses for a texture - // Returns the new texture name or the same texture name when cancelled - public string BrowseTexture(IWin32Window owner, string initialvalue) + // This browses for a texture + // Returns the new texture name or the same texture name when cancelled + public string BrowseTexture(IWin32Window owner, string initialvalue) { return TextureBrowserForm.Browse(owner, initialvalue, false);//mxd } @@ -4106,7 +4145,7 @@ namespace CodeImp.DoomBuilder.Windows if((General.Map != null) && (General.Map.Data != null)) { ImageData img = General.Map.Data.GetFlatImage(imagename); - ImageDataLoaded(img); + ImageDataLoaded(img); } break; @@ -4137,11 +4176,11 @@ namespace CodeImp.DoomBuilder.Windows } break; - case General.WM_MOUSEHWHEEL: - int delta = m.WParam.ToInt32() >> 16; - OnMouseHWheel(delta); - m.Result = new IntPtr(delta); - break; + case General.WM_MOUSEHWHEEL: + int delta = m.WParam.ToInt32() >> 16; + OnMouseHWheel(delta); + m.Result = new IntPtr(delta); + break; default: // Let the base handle the message @@ -4208,11 +4247,11 @@ namespace CodeImp.DoomBuilder.Windows // but only when first loaded or when dimensions were changed internal void ImageDataLoaded(ImageData img) { - // Image is used in the map? - if ((img != null) && img.UsedInMap && !img.IsDisposed) + // Image is used in the map? + if ((img != null) && img.UsedInMap && !img.IsDisposed) { - // Go for all setors - bool updated = false; + // Go for all setors + bool updated = false; long imgshorthash = General.Map.Data.GetShortLongFlatName(img.LongName); //mxd. Part of long name support shennanigans foreach(Sector s in General.Map.Map.Sectors) @@ -4227,7 +4266,7 @@ namespace CodeImp.DoomBuilder.Windows // Update ceiling buffer if needed if(s.LongCeilTexture == img.LongName || s.LongCeilTexture == imgshorthash) { - s.UpdateCeilingSurface(); + s.UpdateCeilingSurface(); updated = true; } } @@ -4235,7 +4274,7 @@ namespace CodeImp.DoomBuilder.Windows // If we made updates, redraw the screen if(updated) DelayedRedraw(); } - } + } public void EnableProcessing() { diff --git a/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs index 841d2734..39f8b911 100755 --- a/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DragGeometryMode.cs @@ -266,7 +266,8 @@ namespace CodeImp.DoomBuilder.BuilderModes if(snapgrid || snapgridincrement) { // Get grid intersection coordinates - List coords = nl.GetGridIntersections(snapgridincrement ? dragstartoffset : new Vector2D()); + List coords = nl.GetGridIntersections(snapgridincrement ? dragstartoffset : new Vector2D(), + General.Map.Grid.GridRotate, General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY); // mxd. Do the rest only if we actually have some coordinates if(coords.Count > 0) diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs index 89caa38e..59c55ca2 100755 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs @@ -421,7 +421,8 @@ namespace CodeImp.DoomBuilder.BuilderModes else if(snaptogrid) { // Get grid intersection coordinates - List coords = nl.GetGridIntersections(); + List coords = nl.GetGridIntersections(General.Map.Grid.GridRotate, + General.Map.Grid.GridOriginX, General.Map.Grid.GridOriginY); // Find nearest grid intersection bool found = false;