2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
#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;
|
2014-11-25 11:52:01 +00:00
|
|
|
using System.IO;
|
2009-04-19 18:07:22 +00:00
|
|
|
using System.Windows.Forms;
|
|
|
|
using CodeImp.DoomBuilder.Windows;
|
|
|
|
using CodeImp.DoomBuilder.IO;
|
|
|
|
using CodeImp.DoomBuilder.Actions;
|
|
|
|
using CodeImp.DoomBuilder.Data;
|
|
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
namespace CodeImp.DoomBuilder.Editing
|
|
|
|
{
|
2016-03-18 12:52:12 +00:00
|
|
|
public class GridSetup : IDisposable
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
#region ================== Constants
|
|
|
|
|
2016-12-27 13:59:20 +00:00
|
|
|
private const float DEFAULT_GRID_SIZE = 32f;
|
|
|
|
internal const float MINIMUM_GRID_SIZE_UDMF = 0.125f; //mxd
|
|
|
|
internal const float MINIMUM_GRID_SIZE = 1.0f; //mxd
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
public const int SOURCE_TEXTURES = 0;
|
|
|
|
public const int SOURCE_FLATS = 1;
|
|
|
|
public const int SOURCE_FILE = 2;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Variables
|
|
|
|
|
|
|
|
// Grid
|
2017-01-06 10:01:59 +00:00
|
|
|
private int gridsize;
|
2020-05-21 12:20:02 +00:00
|
|
|
private double gridsizef;
|
|
|
|
private double gridsizefinv;
|
|
|
|
private double gridrotate;
|
|
|
|
private double gridoriginx, gridoriginy;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Background
|
|
|
|
private string background = "";
|
|
|
|
private int backsource;
|
2020-01-13 18:11:10 +00:00
|
|
|
private ImageData backimage = new UnknownImage();
|
2009-04-19 18:07:22 +00:00
|
|
|
private int backoffsetx, backoffsety;
|
2020-05-21 12:20:02 +00:00
|
|
|
private double backscalex, backscaley;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Disposing
|
|
|
|
private bool isdisposed;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Properties
|
|
|
|
|
2017-01-06 10:01:59 +00:00
|
|
|
public int GridSize { get { return gridsize; } } //mxd
|
2020-05-21 12:20:02 +00:00
|
|
|
public double GridSizeF { get { return gridsizef; } }
|
|
|
|
public double GridRotate { get { return gridrotate; }}
|
|
|
|
public double GridOriginX { get { return gridoriginx; }}
|
|
|
|
public double GridOriginY { get { return gridoriginy; }}
|
2009-04-19 18:07:22 +00:00
|
|
|
internal string BackgroundName { get { return background; } }
|
|
|
|
internal int BackgroundSource { get { return backsource; } }
|
|
|
|
internal ImageData Background { get { return backimage; } }
|
|
|
|
internal int BackgroundX { get { return backoffsetx; } }
|
|
|
|
internal int BackgroundY { get { return backoffsety; } }
|
2020-05-21 12:20:02 +00:00
|
|
|
internal double BackgroundScaleX { get { return backscalex; } }
|
|
|
|
internal double BackgroundScaleY { get { return backscaley; } }
|
2009-04-19 18:07:22 +00:00
|
|
|
internal bool Disposed { get { return isdisposed; } }
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Constructor / Disposer
|
|
|
|
|
|
|
|
// Constructor
|
|
|
|
internal GridSetup()
|
|
|
|
{
|
|
|
|
// Initialize
|
|
|
|
SetGridSize(DEFAULT_GRID_SIZE);
|
|
|
|
backscalex = 1.0f;
|
|
|
|
backscaley = 1.0f;
|
2019-01-14 18:07:08 +00:00
|
|
|
gridrotate = 0.0f;
|
|
|
|
gridoriginx = 0;
|
|
|
|
gridoriginy = 0;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Register actions
|
|
|
|
General.Actions.BindMethods(this);
|
|
|
|
|
|
|
|
// We have no destructor
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disposer
|
2016-03-18 12:52:12 +00:00
|
|
|
public void Dispose()
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
if(!isdisposed)
|
|
|
|
{
|
|
|
|
// Dispose image if needed
|
2016-03-18 12:52:12 +00:00
|
|
|
if(backimage is FileImage) backimage.Dispose();
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Clean up
|
|
|
|
backimage = null;
|
|
|
|
|
|
|
|
// Unregister actions
|
|
|
|
General.Actions.UnbindMethods(this);
|
|
|
|
|
|
|
|
// Done
|
|
|
|
isdisposed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Methods
|
|
|
|
|
|
|
|
// Write settings to configuration
|
|
|
|
internal void WriteToConfig(Configuration cfg, string path)
|
|
|
|
{
|
|
|
|
// Write settings
|
|
|
|
cfg.WriteSetting(path + ".background", background);
|
|
|
|
cfg.WriteSetting(path + ".backsource", backsource);
|
|
|
|
cfg.WriteSetting(path + ".backoffsetx", backoffsetx);
|
|
|
|
cfg.WriteSetting(path + ".backoffsety", backoffsety);
|
|
|
|
cfg.WriteSetting(path + ".backscalex", (int)(backscalex * 100.0f));
|
|
|
|
cfg.WriteSetting(path + ".backscaley", (int)(backscaley * 100.0f));
|
2017-01-06 10:01:59 +00:00
|
|
|
cfg.WriteSetting(path + ".gridsize", gridsizef);
|
2019-01-14 18:07:08 +00:00
|
|
|
cfg.WriteSetting(path + ".gridrotate", gridrotate);
|
|
|
|
cfg.WriteSetting(path + ".gridoriginx", gridoriginx);
|
|
|
|
cfg.WriteSetting(path + ".gridoriginy", gridoriginy);
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read settings from configuration
|
2016-03-23 14:52:33 +00:00
|
|
|
internal void ReadFromConfig(Configuration cfg, string path)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
// Read settings
|
|
|
|
background = cfg.ReadSetting(path + ".background", "");
|
|
|
|
backsource = cfg.ReadSetting(path + ".backsource", 0);
|
|
|
|
backoffsetx = cfg.ReadSetting(path + ".backoffsetx", 0);
|
|
|
|
backoffsety = cfg.ReadSetting(path + ".backoffsety", 0);
|
2014-02-21 14:42:12 +00:00
|
|
|
backscalex = cfg.ReadSetting(path + ".backscalex", 100) / 100.0f;
|
|
|
|
backscaley = cfg.ReadSetting(path + ".backscaley", 100) / 100.0f;
|
2017-01-06 10:01:59 +00:00
|
|
|
gridsizef = cfg.ReadSetting(path + ".gridsize", DEFAULT_GRID_SIZE);
|
2019-01-14 18:07:08 +00:00
|
|
|
gridoriginx = cfg.ReadSetting(path + ".gridoriginx", 0);
|
|
|
|
gridoriginy = cfg.ReadSetting(path + ".gridoriginy", 0);
|
|
|
|
gridrotate = cfg.ReadSetting(path + ".gridrotate", 0.0f);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Setup
|
2017-01-06 10:01:59 +00:00
|
|
|
SetGridSize(gridsizef);
|
2009-04-19 18:07:22 +00:00
|
|
|
LinkBackground();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This sets the grid size
|
2020-05-21 12:20:02 +00:00
|
|
|
internal void SetGridSize(double size)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2014-11-02 17:15:04 +00:00
|
|
|
//mxd. Bad things happen when size <= 0
|
2016-12-27 13:59:20 +00:00
|
|
|
size = Math.Max(size, ((General.Map != null && General.Map.UDMF) ? MINIMUM_GRID_SIZE_UDMF : MINIMUM_GRID_SIZE));
|
2014-11-02 17:15:04 +00:00
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Change grid
|
2017-01-06 10:01:59 +00:00
|
|
|
gridsizef = size;
|
|
|
|
gridsize = (int)Math.Max(1, Math.Round(gridsizef)); //mxd
|
|
|
|
gridsizefinv = 1f / gridsizef;
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Update in main window
|
2017-01-06 10:01:59 +00:00
|
|
|
General.MainWindow.UpdateGrid(gridsizef);
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
2019-01-14 18:07:08 +00:00
|
|
|
// Set the rotation angle of the grid
|
2020-05-21 12:20:02 +00:00
|
|
|
public void SetGridRotation(double angle)
|
2019-01-14 18:07:08 +00:00
|
|
|
{
|
|
|
|
gridrotate = angle;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the origin of the grid
|
2020-05-21 12:20:02 +00:00
|
|
|
public void SetGridOrigin(double x, double y)
|
2019-01-14 18:07:08 +00:00
|
|
|
{
|
|
|
|
gridoriginx = x;
|
|
|
|
gridoriginy = y;
|
|
|
|
}
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// This sets the background
|
|
|
|
internal void SetBackground(string name, int source)
|
|
|
|
{
|
|
|
|
// Set background
|
|
|
|
if(name == null) name = "";
|
|
|
|
this.backsource = source;
|
|
|
|
this.background = name;
|
|
|
|
|
|
|
|
// Find this image
|
|
|
|
LinkBackground();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This sets the background view
|
|
|
|
internal void SetBackgroundView(int offsetx, int offsety, float scalex, float scaley)
|
|
|
|
{
|
|
|
|
// Set background offset
|
|
|
|
this.backoffsetx = offsetx;
|
|
|
|
this.backoffsety = offsety;
|
|
|
|
this.backscalex = scalex;
|
|
|
|
this.backscaley = scaley;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This finds and links the background image
|
|
|
|
internal void LinkBackground()
|
|
|
|
{
|
|
|
|
// Dispose image if needed
|
2016-03-18 12:52:12 +00:00
|
|
|
if(backimage is FileImage) backimage.Dispose();
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Where to load background from?
|
|
|
|
switch(backsource)
|
|
|
|
{
|
|
|
|
case SOURCE_TEXTURES:
|
|
|
|
backimage = General.Map.Data.GetTextureImage(background);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOURCE_FLATS:
|
|
|
|
backimage = General.Map.Data.GetFlatImage(background);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SOURCE_FILE:
|
2014-11-25 11:52:01 +00:00
|
|
|
backimage = new FileImage(Path.GetFileNameWithoutExtension(background), background, false, 1.0f, 1.0f);
|
2009-04-19 18:07:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure it is loaded
|
2020-01-12 22:10:57 +00:00
|
|
|
backimage.LoadImageNow();
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This returns the next higher coordinate
|
2020-05-21 12:20:02 +00:00
|
|
|
public double GetHigher(double offset)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2020-05-21 12:20:02 +00:00
|
|
|
return Math.Round((offset + (gridsizef * 0.5f)) * gridsizefinv) * gridsizef;
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This returns the next lower coordinate
|
2020-05-21 12:20:02 +00:00
|
|
|
public double GetLower(double offset)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2020-05-21 12:20:02 +00:00
|
|
|
return Math.Round((offset - (gridsizef * 0.5f)) * gridsizefinv) * gridsizef;
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This snaps to the nearest grid coordinate
|
|
|
|
public Vector2D SnappedToGrid(Vector2D v)
|
|
|
|
{
|
2019-01-14 18:07:08 +00:00
|
|
|
return SnappedToGrid(v, gridsizef, gridsizefinv, gridrotate, gridoriginx, gridoriginy);
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This snaps to the nearest grid coordinate
|
2020-05-21 12:20:02 +00:00
|
|
|
public static Vector2D SnappedToGrid(Vector2D v, double gridsize, double gridsizeinv, double gridrotate = 0.0f, double gridoriginx = 0, double gridoriginy = 0)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2019-01-14 18:07:08 +00:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2020-05-21 12:20:02 +00:00
|
|
|
Vector2D sv = new Vector2D(Math.Round(v.x * gridsizeinv) * gridsize,
|
|
|
|
Math.Round(v.y * gridsizeinv) * gridsize);
|
2010-08-13 18:32:21 +00:00
|
|
|
|
2019-01-14 18:07:08 +00:00
|
|
|
if (transformed)
|
|
|
|
{
|
|
|
|
// Put back into original frame
|
|
|
|
sv = sv.GetRotated(gridrotate) + origin;
|
|
|
|
}
|
|
|
|
|
2015-12-28 15:01:53 +00:00
|
|
|
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;
|
2010-08-13 18:32:21 +00:00
|
|
|
|
2015-12-28 15:01:53 +00:00
|
|
|
if(sv.y > General.Map.Config.TopBoundary) sv.y = General.Map.Config.TopBoundary;
|
|
|
|
else if(sv.y < General.Map.Config.BottomBoundary) sv.y = General.Map.Config.BottomBoundary;
|
2010-08-13 18:32:21 +00:00
|
|
|
|
|
|
|
return sv;
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Actions
|
|
|
|
|
|
|
|
// This shows the grid setup dialog
|
2014-12-03 23:15:26 +00:00
|
|
|
internal static void ShowGridSetup()
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
// Show preferences dialog
|
|
|
|
GridSetupForm gridform = new GridSetupForm();
|
|
|
|
if(gridform.ShowDialog(General.MainWindow) == DialogResult.OK)
|
|
|
|
{
|
|
|
|
// Redraw display
|
|
|
|
General.MainWindow.RedrawDisplay();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Done
|
|
|
|
gridform.Dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This changes grid size
|
2009-05-17 14:58:45 +00:00
|
|
|
// Note: these were incorrectly swapped before, hence the wrong action name
|
2009-04-19 18:07:22 +00:00
|
|
|
[BeginAction("gridinc")]
|
2009-05-17 14:58:45 +00:00
|
|
|
internal void DecreaseGrid()
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2016-12-27 13:59:20 +00:00
|
|
|
//mxd. Not lower than 0.125 in UDMF or 1 otherwise
|
|
|
|
float preminsize = (General.Map.UDMF ? MINIMUM_GRID_SIZE_UDMF * 2 : MINIMUM_GRID_SIZE * 2);
|
2017-01-06 10:01:59 +00:00
|
|
|
if(gridsizef >= preminsize)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2016-03-04 13:41:55 +00:00
|
|
|
//mxd. Disable automatic grid resizing
|
|
|
|
General.MainWindow.DisableDynamicGridResize();
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Change grid
|
2017-01-06 10:01:59 +00:00
|
|
|
SetGridSize(gridsizef / 2);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Redraw display
|
|
|
|
General.MainWindow.RedrawDisplay();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This changes grid size
|
2009-05-17 14:58:45 +00:00
|
|
|
// Note: these were incorrectly swapped before, hence the wrong action name
|
2009-04-19 18:07:22 +00:00
|
|
|
[BeginAction("griddec")]
|
2009-05-17 14:58:45 +00:00
|
|
|
internal void IncreaseGrid()
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
// Not higher than 1024
|
2017-01-06 10:01:59 +00:00
|
|
|
if(gridsizef <= 512)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2016-03-04 13:41:55 +00:00
|
|
|
//mxd. Disable automatic grid resizing
|
|
|
|
General.MainWindow.DisableDynamicGridResize();
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
// Change grid
|
2017-01-06 10:01:59 +00:00
|
|
|
SetGridSize(gridsizef * 2);
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
// Redraw display
|
|
|
|
General.MainWindow.RedrawDisplay();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|