mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-29 23:22:32 +00:00
372 lines
11 KiB
C#
372 lines
11 KiB
C#
#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<http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#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.Threading;
|
|
using System.Windows.Forms;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using CodeImp.DoomBuilder.BuilderModes.IO;
|
|
|
|
namespace CodeImp.DoomBuilder.BuilderModes.Interface
|
|
{
|
|
enum ImageExportResult
|
|
{
|
|
OK,
|
|
Canceled,
|
|
OutOfMemory,
|
|
ImageTooBig
|
|
}
|
|
|
|
public partial class ImageExportSettingsForm : Form
|
|
{
|
|
#region ================== Properties
|
|
|
|
public string FilePath { get { return tbExportPath.Text.Trim(); } }
|
|
public bool Floor { get { return rbFloor.Checked; } }
|
|
public bool Fullbright { get { return cbFullbright.Checked; } }
|
|
public bool Transparency { get { return cbTransparency.Checked; } }
|
|
public bool ApplySectorColors { get { return cbApplySectorColors.Checked; } }
|
|
public bool Brightmap { get { return cbBrightmap.Checked; } }
|
|
public bool Tiles { get { return cbTiles.Checked; } }
|
|
public float ImageScale { get { return (float)Math.Pow(2, cbScale.SelectedIndex); } }
|
|
|
|
#endregion
|
|
|
|
#region ================== Delegates
|
|
|
|
private delegate void CallVoidMethodDeletage();
|
|
private delegate void CallStringMethodDeletage(string s);
|
|
private delegate void CallImageExportResultMethodDeletage(ImageExportResult ier);
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
Thread exportthread;
|
|
bool exporting;
|
|
bool cancelexport;
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor
|
|
|
|
public ImageExportSettingsForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
cbImageFormat.SelectedIndex = 0;
|
|
cbPixelFormat.SelectedIndex = 0;
|
|
exporting = false;
|
|
cancelexport = false;
|
|
|
|
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;
|
|
}
|
|
|
|
cbFullbright.Checked = General.Settings.ReadPluginSetting("imageexportfullbright", true);
|
|
cbApplySectorColors.Checked = General.Settings.ReadPluginSetting("imageexportapplysectorcolors", true);
|
|
cbTransparency.Checked = General.Settings.ReadPluginSetting("imageexporttransparency", false);
|
|
cbBrightmap.Checked = General.Settings.ReadPluginSetting("imageexportbrightmap", false);
|
|
cbTiles.Checked = General.Settings.ReadPluginSetting("imageexporttiles", false);
|
|
cbScale.SelectedIndex = General.Settings.ReadPluginSetting("imageexportscale", 0);
|
|
}
|
|
|
|
#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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts exporting the image(s). Disables all controls and starts the thread that does the actual exporting.
|
|
/// </summary>
|
|
private void StartExport()
|
|
{
|
|
ICollection<Sector> sectors = General.Map.Map.SelectedSectorsCount == 0 ? General.Map.Map.Sectors : General.Map.Map.GetSelectedSectors(true);
|
|
|
|
exporting = true;
|
|
cancelexport = false;
|
|
|
|
progress.Maximum = 100; //sectors.Count * (Brightmap ? 2 : 1);
|
|
progress.Value = 0;
|
|
progress.Visible = true;
|
|
|
|
lbPhase.Text = "";
|
|
lbPhase.Visible = true;
|
|
|
|
foreach (Control c in Controls)
|
|
{
|
|
if (!(c is ProgressBar || c is Label))
|
|
c.Enabled = false;
|
|
}
|
|
|
|
export.Enabled = true;
|
|
export.Text = "Cancel";
|
|
|
|
ImageExportSettings settings = new ImageExportSettings(Path.GetDirectoryName(FilePath), Path.GetFileNameWithoutExtension(FilePath), Path.GetExtension(FilePath), Floor, Fullbright, ApplySectorColors, Brightmap, Transparency, Tiles, ImageScale, GetPixelFormat(), GetImageFormat());
|
|
|
|
exportthread = new Thread(() => RunExport(settings))
|
|
{
|
|
Name = "Image export",
|
|
Priority = ThreadPriority.Normal
|
|
};
|
|
exportthread.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enables all controls. This has to be called when the export is finished (either successfully or unsuccessfully)
|
|
/// </summary>
|
|
/// <param name="ier">Image export result</param>
|
|
private void StopExport(ImageExportResult ier)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
CallImageExportResultMethodDeletage d = StopExport;
|
|
this.Invoke(d, ier);
|
|
}
|
|
else
|
|
{
|
|
progress.Visible = false;
|
|
lbPhase.Visible = false;
|
|
|
|
foreach (Control c in Controls)
|
|
{
|
|
if (!(c is ProgressBar || c is Label))
|
|
c.Enabled = true;
|
|
}
|
|
|
|
export.Text = "Export";
|
|
|
|
if (ier == ImageExportResult.OK)
|
|
MessageBox.Show("Export successful.", "Export to image", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
else if(ier == ImageExportResult.Canceled)
|
|
MessageBox.Show("Export canceled.", "Export to image", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
else if (ier == ImageExportResult.OutOfMemory)
|
|
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);
|
|
else if(ier == ImageExportResult.ImageTooBig)
|
|
MessageBox.Show("Exporting failed. The image is likely too big for the current settings. Try a lower color depth or file format", "Export failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
|
|
exporting = false;
|
|
}
|
|
|
|
private bool CheckCancelExport()
|
|
{
|
|
return cancelexport;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows the current phase in textual form. Is called by the exporter
|
|
/// </summary>
|
|
/// <param name="text"></param>
|
|
private void ShowPhase(string text)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
CallStringMethodDeletage d = ShowPhase;
|
|
this.Invoke(d, text);
|
|
}
|
|
else
|
|
{
|
|
lbPhase.Text = text;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds progress to the progress bar. Is called by the exporter
|
|
/// </summary>
|
|
private void AddProgress()
|
|
{
|
|
if (progress.InvokeRequired)
|
|
{
|
|
CallVoidMethodDeletage d = AddProgress;
|
|
try { progress.Invoke(d); }
|
|
catch (ThreadInterruptedException) { }
|
|
}
|
|
else
|
|
{
|
|
// Just winforms things to make the progress bar animation not lag behind
|
|
int value = progress.Value + 1;
|
|
progress.Value = value;
|
|
progress.Value = value - 1;
|
|
progress.Value = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs the actual exporter
|
|
/// </summary>
|
|
/// <param name="settings">Export settings</param>
|
|
private void RunExport(ImageExportSettings settings)
|
|
{
|
|
ICollection<Sector> sectors = General.Map.Map.SelectedSectorsCount == 0 ? General.Map.Map.Sectors : General.Map.Map.GetSelectedSectors(true);
|
|
|
|
ImageExporter exporter = new ImageExporter(sectors, settings, AddProgress, ShowPhase, CheckCancelExport);
|
|
|
|
try
|
|
{
|
|
exporter.Export();
|
|
}
|
|
catch (ArgumentException) // Happens if there's not enough consecutive memory to create the file
|
|
{
|
|
StopExport(ImageExportResult.OutOfMemory);
|
|
return;
|
|
}
|
|
catch(ImageExportCanceledException)
|
|
{
|
|
StopExport(ImageExportResult.Canceled);
|
|
return;
|
|
}
|
|
catch(ImageExportImageTooBigException)
|
|
{
|
|
StopExport(ImageExportResult.ImageTooBig);
|
|
return;
|
|
}
|
|
|
|
StopExport(ImageExportResult.OK);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Events
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void close_Click(object sender, EventArgs e)
|
|
{
|
|
this.DialogResult = DialogResult.Cancel;
|
|
this.Close();
|
|
}
|
|
|
|
private void export_Click(object sender, EventArgs e)
|
|
{
|
|
if (exporting)
|
|
{
|
|
cancelexport = true;
|
|
export.Enabled = false;
|
|
}
|
|
else
|
|
{
|
|
General.Settings.WritePluginSetting("imageexportfullbright", cbFullbright.Checked);
|
|
General.Settings.WritePluginSetting("imageexportapplysectorcolors", cbApplySectorColors.Checked);
|
|
General.Settings.WritePluginSetting("imageexportbrightmap", cbBrightmap.Checked);
|
|
General.Settings.WritePluginSetting("imageexporttransparency", cbTransparency.Checked);
|
|
General.Settings.WritePluginSetting("imageexporttiles", cbTiles.Checked);
|
|
General.Settings.WritePluginSetting("imageexportscale", cbScale.SelectedIndex);
|
|
|
|
// Exporting works like this:
|
|
// In here StartExport() is called
|
|
// StartExport() disables all controls and creates a thread that runs RunExport() in the background; then the StartExport method ends
|
|
// RunExport() creates an instance of ImageExporter and starts the actual export
|
|
// When ImageExporter finishes its job it runs StopExport()
|
|
// StopExport() enables all controls again
|
|
|
|
StartExport();
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
private void ImageExportSettingsForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
// Do not allow closing the form while the export is running
|
|
if (exporting)
|
|
e.Cancel = true;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|