From dcaf0a525dd0df6783ee0681464dbac7714f8afa Mon Sep 17 00:00:00 2001
From: biwa <6475593+biwa@users.noreply.github.com>
Date: Wed, 17 Jun 2020 22:22:00 +0200
Subject: [PATCH] Added feature to export the selected sectors as an image
---
.../Plugins/BuilderModes/BuilderModes.csproj | 10 +
.../BuilderModes/General/BuilderPlug.cs | 32 +++
.../Plugins/BuilderModes/IO/ImageExporter.cs | 155 +++++++++++++
.../ImageExportSettingsForm.Designer.cs | 205 ++++++++++++++++++
.../Interface/ImageExportSettingsForm.cs | 149 +++++++++++++
.../Interface/ImageExportSettingsForm.resx | 123 +++++++++++
.../Interface/MenusForm.Designer.cs | 16 +-
.../BuilderModes/Resources/Actions.cfg | 10 +
8 files changed, 698 insertions(+), 2 deletions(-)
create mode 100644 Source/Plugins/BuilderModes/IO/ImageExporter.cs
create mode 100644 Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.Designer.cs
create mode 100644 Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.cs
create mode 100644 Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.resx
diff --git a/Source/Plugins/BuilderModes/BuilderModes.csproj b/Source/Plugins/BuilderModes/BuilderModes.csproj
index 0d76312..180c7a9 100644
--- a/Source/Plugins/BuilderModes/BuilderModes.csproj
+++ b/Source/Plugins/BuilderModes/BuilderModes.csproj
@@ -146,6 +146,12 @@
FindReplaceForm.cs
+
+ Form
+
+
+ ImageExportSettingsForm.cs
+
Form
@@ -200,6 +206,7 @@
VertexSlopeAssistTagForm.cs
+
True
True
@@ -239,6 +246,9 @@
VertexSlopeAssistTagForm.cs
+
+
+ ImageExportSettingsForm.cs
diff --git a/Source/Plugins/BuilderModes/General/BuilderPlug.cs b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
index 475b099..c67237e 100644
--- a/Source/Plugins/BuilderModes/General/BuilderPlug.cs
+++ b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
@@ -875,6 +875,38 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
}
+ [BeginAction("exporttoimage")]
+ private void ExportToImage()
+ {
+ // Convert geometry selection to sectors
+ General.Map.Map.ConvertSelection(SelectionType.Sectors);
+
+ // Get sectors
+ ICollection sectors = General.Map.Map.SelectedSectorsCount == 0 ? General.Map.Map.Sectors : General.Map.Map.GetSelectedSectors(true);
+ if (sectors.Count == 0)
+ {
+ General.Interface.DisplayStatus(StatusType.Warning, "Image export failed. Map has no sectors!");
+ return;
+ }
+
+ ImageExporter exporter = new ImageExporter();
+
+ ImageExportSettingsForm form = new ImageExportSettingsForm();
+ if (form.ShowDialog() == DialogResult.OK)
+ {
+ ImageExportSettings settings = new ImageExportSettings(Path.GetFileName(form.FilePath), Path.GetDirectoryName(form.FilePath), form.Floor, form.GetPixelFormat(), form.GetImageFormat());
+
+ try
+ {
+ exporter.Export(sectors, settings);
+ }
+ catch(ArgumentException e) // Happens if there's not enough consecutive memory so create the file
+ {
+ MessageBox.Show("Exporting failed. There's likely not enough consecutive free memory to create the image. Try a lower color depth or file format", "Export failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+ }
+
#endregion
}
}
diff --git a/Source/Plugins/BuilderModes/IO/ImageExporter.cs b/Source/Plugins/BuilderModes/IO/ImageExporter.cs
new file mode 100644
index 0000000..ebdfe5f
--- /dev/null
+++ b/Source/Plugins/BuilderModes/IO/ImageExporter.cs
@@ -0,0 +1,155 @@
+#region ================== Copyright (c) 2020 Boris Iwanski
+
+/*
+ * This program is free software: you can redistribute it and/or modify
+ *
+ * it under the terms of the GNU General Public License as published by
+ *
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.If not, see.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Linq;
+using System.Text;
+using CodeImp.DoomBuilder.Geometry;
+using CodeImp.DoomBuilder.Map;
+using System.Diagnostics;
+
+namespace CodeImp.DoomBuilder.BuilderModes.IO
+{
+ internal struct ImageExportSettings
+ {
+ public string Name;
+ public string Path;
+ public bool Floor;
+ public PixelFormat PixelFormat;
+ public ImageFormat ImageFormat;
+
+ public ImageExportSettings(string name, string path, bool floor, PixelFormat pformat, ImageFormat iformat)
+ {
+ Name = name;
+ Path = path;
+ Floor = floor;
+ PixelFormat = pformat;
+ ImageFormat = iformat;
+ }
+ }
+
+ internal class ImageExporter
+ {
+ public void Export(ICollection sectors, ImageExportSettings settings)
+ {
+ Bitmap bitmap;
+ Vector2D offset = new Vector2D(float.MaxValue, float.MinValue);
+ Vector2D size = new Vector2D(float.MinValue, float.MaxValue);
+
+ HashSet vertices = new HashSet();
+
+ // Find the top left and bottom right corners of the selection
+ foreach(Sector s in sectors)
+ {
+ foreach (Sidedef sd in s.Sidedefs)
+ {
+ foreach (Vertex v in new Vertex[] { sd.Line.Start, sd.Line.End })
+ {
+ if (v.Position.x < offset.x)
+ offset.x = v.Position.x;
+
+ if (v.Position.x > size.x)
+ size.x = v.Position.x;
+
+ if (v.Position.y > offset.y)
+ offset.y = v.Position.y;
+
+ if (v.Position.y < size.y)
+ size.y = v.Position.y;
+ }
+ }
+ }
+
+ // Right now "size" is the bottom right corener of the selection, so subtract the offset
+ // (top left corner of the selection). y will always be negative, so make it positive
+ size -= offset;
+ size.y *= -1.0f;
+
+ bitmap = new Bitmap((int)size.x, (int)size.y, settings.PixelFormat);
+
+ Graphics g = Graphics.FromImage(bitmap);
+ g.Clear(Color.Black); // If we don't clear to black we'll see seams where the sectors touch, due to the AA
+ g.InterpolationMode = InterpolationMode.HighQualityBilinear;
+ g.CompositingQuality = CompositingQuality.HighQuality;
+ g.PixelOffsetMode = PixelOffsetMode.HighQuality;
+ g.SmoothingMode = SmoothingMode.AntiAlias; // Without AA the sector edges will be quite rough
+
+ foreach (Sector s in sectors)
+ {
+ GraphicsPath p = new GraphicsPath();
+ float rotation = (float)s.Fields.GetValue("rotationfloor", 0.0);
+
+ // If a sector is rotated any offset is on the rotated axes. But we need to offset by
+ // map coordinates. We'll use this vector to compute that offset
+ Vector2D rotationvector = Vector2D.FromAngle(Angle2D.DegToRad(rotation) + Angle2D.PIHALF);
+
+ // Sectors are triangulated, so draw every triangle
+ for (int i = 0; i < s.Triangles.Vertices.Count / 3; i++)
+ {
+ // The GDI image has the 0/0 coordinate in the top left, so invert the y component
+ Vector2D v1 = s.Triangles.Vertices[i * 3] - offset; v1.y *= -1.0f;
+ Vector2D v2 = s.Triangles.Vertices[i * 3 + 1] - offset; v2.y *= -1.0f;
+ Vector2D v3 = s.Triangles.Vertices[i * 3 + 2] - offset; v3.y *= -1.0f;
+
+ p.AddLine((float)v1.x, (float)v1.y, (float)v2.x, (float)v2.y);
+ p.AddLine((float)v2.x, (float)v2.y, (float)v3.x, (float)v3.y);
+ p.CloseFigure();
+ }
+
+ Bitmap texture;
+
+ if(settings.Floor)
+ texture = General.Map.Data.GetFlatImage(s.FloorTexture).GetBitmap();
+ else
+ texture = General.Map.Data.GetFlatImage(s.CeilTexture).GetBitmap();
+
+ Vector2D textureoffset = new Vector2D();
+ textureoffset.x = s.Fields.GetValue("xpanningfloor", 0.0f);
+ textureoffset.y = s.Fields.GetValue("ypanningfloor", 0.0f);
+
+ // Create the transformation matrix
+ Matrix matrix = new Matrix();
+ matrix.Rotate(rotation);
+ matrix.Translate((float)(-offset.x * rotationvector.x), (float)(offset.x * rotationvector.y)); // Left/right offset from the map origin
+ matrix.Translate((float)(offset.y * rotationvector.y), (float)(offset.y * rotationvector.x)); // Up/down offset from the map origin
+ matrix.Translate(-(float)textureoffset.x, -(float)textureoffset.y); // Texture offset
+
+ // Create the texture brush and apply the matrix
+ TextureBrush t = new TextureBrush(texture);
+ t.Transform = matrix;
+
+ // Draw the islands of the sector
+ g.FillPath(t, p);
+
+ }
+
+ // Finally save the image
+ bitmap.Save(Path.Combine(settings.Path, settings.Name), settings.ImageFormat);
+ }
+ }
+}
diff --git a/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.Designer.cs
new file mode 100644
index 0000000..fb9165d
--- /dev/null
+++ b/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.Designer.cs
@@ -0,0 +1,205 @@
+namespace CodeImp.DoomBuilder.BuilderModes.Interface
+{
+ partial class ImageExportSettingsForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.tbExportPath = new System.Windows.Forms.TextBox();
+ this.browse = new System.Windows.Forms.Button();
+ this.label1 = new System.Windows.Forms.Label();
+ this.cancel = new System.Windows.Forms.Button();
+ this.export = new System.Windows.Forms.Button();
+ this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
+ this.cbImageFormat = new System.Windows.Forms.ComboBox();
+ this.cbPixelFormat = new System.Windows.Forms.ComboBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.rbFloor = new System.Windows.Forms.RadioButton();
+ this.rbCeiling = new System.Windows.Forms.RadioButton();
+ this.SuspendLayout();
+ //
+ // tbExportPath
+ //
+ this.tbExportPath.Location = new System.Drawing.Point(50, 9);
+ this.tbExportPath.Name = "tbExportPath";
+ this.tbExportPath.Size = new System.Drawing.Size(344, 20);
+ this.tbExportPath.TabIndex = 2;
+ //
+ // browse
+ //
+ this.browse.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Folder;
+ this.browse.Location = new System.Drawing.Point(400, 7);
+ this.browse.Name = "browse";
+ this.browse.Size = new System.Drawing.Size(30, 24);
+ this.browse.TabIndex = 3;
+ this.browse.UseVisualStyleBackColor = true;
+ this.browse.Click += new System.EventHandler(this.browse_Click);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(12, 12);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(32, 13);
+ this.label1.TabIndex = 4;
+ this.label1.Text = "Path:";
+ //
+ // cancel
+ //
+ this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancel.Location = new System.Drawing.Point(360, 110);
+ this.cancel.Name = "cancel";
+ this.cancel.Size = new System.Drawing.Size(75, 23);
+ this.cancel.TabIndex = 7;
+ this.cancel.Text = "Cancel";
+ this.cancel.UseVisualStyleBackColor = true;
+ this.cancel.Click += new System.EventHandler(this.cancel_Click);
+ //
+ // export
+ //
+ this.export.Location = new System.Drawing.Point(279, 110);
+ this.export.Name = "export";
+ this.export.Size = new System.Drawing.Size(75, 23);
+ this.export.TabIndex = 6;
+ this.export.Text = "Export";
+ this.export.UseVisualStyleBackColor = true;
+ this.export.Click += new System.EventHandler(this.export_Click);
+ //
+ // saveFileDialog
+ //
+ this.saveFileDialog.Filter = "PNG (*.png)|*.png|JPEG (*.jpg)|*.jpg|All files (*.*)|*.*";
+ //
+ // cbImageFormat
+ //
+ this.cbImageFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cbImageFormat.FormattingEnabled = true;
+ this.cbImageFormat.Items.AddRange(new object[] {
+ "PNG",
+ "JPG"});
+ this.cbImageFormat.Location = new System.Drawing.Point(102, 35);
+ this.cbImageFormat.Name = "cbImageFormat";
+ this.cbImageFormat.Size = new System.Drawing.Size(71, 21);
+ this.cbImageFormat.TabIndex = 8;
+ this.cbImageFormat.SelectedIndexChanged += new System.EventHandler(this.cbImageFormat_SelectedIndexChanged);
+ //
+ // cbPixelFormat
+ //
+ this.cbPixelFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cbPixelFormat.FormattingEnabled = true;
+ this.cbPixelFormat.Items.AddRange(new object[] {
+ "32 bit",
+ "24 bit",
+ "16 bit"});
+ this.cbPixelFormat.Location = new System.Drawing.Point(102, 62);
+ this.cbPixelFormat.Name = "cbPixelFormat";
+ this.cbPixelFormat.Size = new System.Drawing.Size(71, 21);
+ this.cbPixelFormat.TabIndex = 9;
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(12, 38);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(71, 13);
+ this.label2.TabIndex = 10;
+ this.label2.Text = "Image format:";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(12, 65);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(64, 13);
+ this.label3.TabIndex = 11;
+ this.label3.Text = "Color depth:";
+ //
+ // rbFloor
+ //
+ this.rbFloor.AutoSize = true;
+ this.rbFloor.Checked = true;
+ this.rbFloor.Location = new System.Drawing.Point(227, 38);
+ this.rbFloor.Name = "rbFloor";
+ this.rbFloor.Size = new System.Drawing.Size(48, 17);
+ this.rbFloor.TabIndex = 12;
+ this.rbFloor.TabStop = true;
+ this.rbFloor.Text = "Floor";
+ this.rbFloor.UseVisualStyleBackColor = true;
+ //
+ // rbCeiling
+ //
+ this.rbCeiling.AutoSize = true;
+ this.rbCeiling.Location = new System.Drawing.Point(227, 60);
+ this.rbCeiling.Name = "rbCeiling";
+ this.rbCeiling.Size = new System.Drawing.Size(56, 17);
+ this.rbCeiling.TabIndex = 13;
+ this.rbCeiling.Text = "Ceiling";
+ this.rbCeiling.UseVisualStyleBackColor = true;
+ //
+ // ImageExportSettingsForm
+ //
+ this.AcceptButton = this.export;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.cancel;
+ this.ClientSize = new System.Drawing.Size(447, 145);
+ this.Controls.Add(this.rbCeiling);
+ this.Controls.Add(this.rbFloor);
+ this.Controls.Add(this.label3);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.cbPixelFormat);
+ this.Controls.Add(this.cbImageFormat);
+ this.Controls.Add(this.cancel);
+ this.Controls.Add(this.export);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.browse);
+ this.Controls.Add(this.tbExportPath);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "ImageExportSettingsForm";
+ this.Text = "Image export settings";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button browse;
+ private System.Windows.Forms.TextBox tbExportPath;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button cancel;
+ private System.Windows.Forms.Button export;
+ private System.Windows.Forms.SaveFileDialog saveFileDialog;
+ private System.Windows.Forms.ComboBox cbImageFormat;
+ private System.Windows.Forms.ComboBox cbPixelFormat;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.RadioButton rbFloor;
+ private System.Windows.Forms.RadioButton rbCeiling;
+ }
+}
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.cs b/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.cs
new file mode 100644
index 0000000..705ad2d
--- /dev/null
+++ b/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.cs
@@ -0,0 +1,149 @@
+#region ================== Copyright (c) 2020 Boris Iwanski
+
+/*
+ * This program is free software: you can redistribute it and/or modify
+ *
+ * it under the terms of the GNU General Public License as published by
+ *
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.If not, see.
+ */
+
+#endregion
+
+using System;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace CodeImp.DoomBuilder.BuilderModes.Interface
+{
+ public partial class ImageExportSettingsForm : Form
+ {
+ #region ================== Properties
+
+ public string FilePath { get { return tbExportPath.Text.Trim(); } }
+ public bool Floor { get { return rbFloor.Checked; } }
+
+ #endregion
+
+
+ #region ================== Constructor
+
+ public ImageExportSettingsForm()
+ {
+ InitializeComponent();
+
+ cbImageFormat.SelectedIndex = 0;
+ cbPixelFormat.SelectedIndex = 0;
+
+ string name = Path.GetFileNameWithoutExtension(General.Map.FileTitle) + "_" + General.Map.Options.LevelName + "_" + Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
+
+ if (string.IsNullOrEmpty(General.Map.FilePathName))
+ {
+ saveFileDialog.FileName = name;
+ }
+ else
+ {
+ saveFileDialog.InitialDirectory = Path.GetDirectoryName(General.Map.FilePathName);
+ saveFileDialog.FileName = Path.GetDirectoryName(General.Map.FilePathName) + Path.DirectorySeparatorChar + name + ".png";
+ tbExportPath.Text = saveFileDialog.FileName;
+ }
+ }
+
+ #endregion
+
+ #region ================== Methods
+
+ public ImageFormat GetImageFormat()
+ {
+ switch(cbImageFormat.SelectedIndex)
+ {
+ case 1: // JPG
+ return ImageFormat.Jpeg;
+ default: // PNG
+ return ImageFormat.Png;
+ }
+ }
+
+ public PixelFormat GetPixelFormat()
+ {
+ switch(cbPixelFormat.SelectedIndex)
+ {
+ case 1: // 24 bit
+ return PixelFormat.Format24bppRgb;
+ case 2: // 16 bit
+ return PixelFormat.Format16bppRgb555;
+ default: // 32 bit
+ return PixelFormat.Format32bppArgb;
+ }
+ }
+
+ private void browse_Click(object sender, EventArgs e)
+ {
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ tbExportPath.Text = saveFileDialog.FileName;
+
+ string extension = Path.GetExtension(saveFileDialog.FileName);
+
+ switch(extension)
+ {
+ case ".jpg":
+ cbImageFormat.SelectedIndex = 1;
+ break;
+ default:
+ cbImageFormat.SelectedIndex = 0;
+ break;
+ }
+ }
+ }
+
+ #endregion
+
+ private void cancel_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ this.Close();
+ }
+
+ private void export_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.OK;
+ this.Close();
+ }
+
+ private void cbImageFormat_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ string newextension = "";
+
+ switch (cbImageFormat.SelectedIndex)
+ {
+ case 1: // JPG
+ newextension = ".jpg";
+ break;
+ default: // PNG
+ newextension = ".png";
+ break;
+ }
+
+ tbExportPath.Text = Path.ChangeExtension(tbExportPath.Text, newextension);
+ }
+ }
+}
diff --git a/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.resx b/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.resx
new file mode 100644
index 0000000..5e7f0a6
--- /dev/null
+++ b/Source/Plugins/BuilderModes/Interface/ImageExportSettingsForm.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs
index 6ff53db..314c0f3 100644
--- a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs
+++ b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs
@@ -129,6 +129,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.itempastepropsoptions = new System.Windows.Forms.ToolStripMenuItem();
this.alignsectorlinedefsitem = new System.Windows.Forms.ToolStripMenuItem();
this.alignlinedefsitem = new System.Windows.Forms.ToolStripMenuItem();
+ this.selectionToImageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menustrip.SuspendLayout();
this.manualstrip.SuspendLayout();
this.fileMenuStrip.SuspendLayout();
@@ -583,6 +584,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.selectSimilarThingsItem.Text = "Select Similar...";
this.selectSimilarThingsItem.Click += new System.EventHandler(this.InvokeTaggedAction);
//
+ // selectionToImageToolStripMenuItem
+ //
+ this.selectionToImageToolStripMenuItem.Name = "selectionToImageToolStripMenuItem";
+ this.selectionToImageToolStripMenuItem.Size = new System.Drawing.Size(226, 22);
+ this.selectionToImageToolStripMenuItem.Tag = "exporttoimage";
+ this.selectionToImageToolStripMenuItem.Text = "Selection to image";
+ this.selectionToImageToolStripMenuItem.Click += new System.EventHandler(this.InvokeTaggedAction);
+ //
+ //
// vertsmenu
//
this.vertsmenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -1026,9 +1036,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
// exportStripMenuItem
//
this.exportStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.toolStripMenuItem5});
+ this.toolStripMenuItem5,
+ this.selectionToImageToolStripMenuItem});
this.exportStripMenuItem.Name = "exportStripMenuItem";
- this.exportStripMenuItem.Size = new System.Drawing.Size(52, 20);
+ this.exportStripMenuItem.Size = new System.Drawing.Size(53, 20);
this.exportStripMenuItem.Text = "Export";
//
// toolStripMenuItem5
@@ -1229,5 +1240,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
private System.Windows.Forms.ToolStripMenuItem vertexSlopeAssistT;
private System.Windows.Forms.ToolStripMenuItem alignsectorlinedefsitem;
private System.Windows.Forms.ToolStripMenuItem alignlinedefsitem;
+ private System.Windows.Forms.ToolStripMenuItem selectionToImageToolStripMenuItem;
}
}
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/Resources/Actions.cfg b/Source/Plugins/BuilderModes/Resources/Actions.cfg
index c1d5401..18bf749 100644
--- a/Source/Plugins/BuilderModes/Resources/Actions.cfg
+++ b/Source/Plugins/BuilderModes/Resources/Actions.cfg
@@ -1683,6 +1683,16 @@ exporttoobj
allowscroll = false;
}
+exporttoimage
+{
+ title = "Export to image";
+ category = "tools";
+ description = "Exports selected sectors (or the whole map if no sectors selected) to an image";
+ allowkeys = true;
+ allowmouse = false;
+ allowscroll = false;
+}
+
flooralignmode
{
title = "Floor Align Mode";