UltimateZoneBuilder/Source/Plugins/3DFloorMode/Windows/ThreeDFloorEditorWindow.cs

312 lines
8.6 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Plugins;
using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Types;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Data;
namespace CodeImp.DoomBuilder.ThreeDFloorMode
{
public partial class ThreeDFloorEditorWindow : Form
{
List<ThreeDFloor> threedfloors;
List<Sector> selectedsectors;
List<ThreeDFloorHelperControl> controlpool;
public List<Sector> SelectedSectors { get { return selectedsectors; } }
public List<ThreeDFloor> ThreeDFloors { get { return threedfloors; } set { threedfloors = value; } }
public ThreeDFloorEditorWindow()
{
this.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width/2, Screen.PrimaryScreen.WorkingArea.Height/2);
controlpool = new List<ThreeDFloorHelperControl>();
InitializeComponent();
}
private void ThreeDFloorEditorWindow_Load(object sender, EventArgs e)
{
selectedsectors = new List<Sector>(General.Map.Map.GetSelectedSectors(true));
sharedThreeDFloorsCheckBox.Checked = false;
FillThreeDFloorPanel(threedfloors);
}
// Gets a control from the pool or creates a new one
private ThreeDFloorHelperControl GetThreeDFloorControl()
{
ThreeDFloorHelperControl ctrl = controlpool.FirstOrDefault(o => o.Used == false);
if (ctrl == null)
{
ctrl = new ThreeDFloorHelperControl();
ctrl.Used = true;
controlpool.Add(ctrl);
threeDFloorPanel.Controls.Add(ctrl);
}
else
{
ctrl.SetDefaults();
ctrl.Used = true;
}
return ctrl;
}
private void okButton_Click(object sender, EventArgs e)
{
threedfloors = new List<ThreeDFloor>();
foreach (ThreeDFloorHelperControl ctrl in threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>())
{
if (ctrl.Used)
{
ctrl.ApplyToThreeDFloor();
threedfloors.Add(ctrl.ThreeDFloor);
}
}
this.DialogResult = DialogResult.OK;
this.Close();
}
private void cancelButton_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
public void addThreeDFloorButton_Click(object sender, EventArgs e)
{
ThreeDFloorHelperControl ctrl = GetThreeDFloorControl();
ctrl.Show();
threeDFloorPanel.ScrollControlIntoView(ctrl);
no3dfloorspanel.Hide();
}
public void DuplicateThreeDFloor(ThreeDFloorHelperControl ctrl)
{
ThreeDFloorHelperControl dup = GetThreeDFloorControl();
dup.Update(ctrl);
dup.Show();
threeDFloorPanel.ScrollControlIntoView(dup);
}
/// <summary>
/// Splits the 3D floor, creating a new 3D floor for every checked sector
/// </summary>
/// <param name="ctrl">The control for the 3D floor that's to be split</param>
public void SplitThreeDFloor(ThreeDFloorHelperControl ctrl)
{
List<int> items = new List<int>();
List<ThreeDFloorHelperControl> controls = new List<ThreeDFloorHelperControl>() { ctrl };
int numsplits = 0;
// Create a list of all checked sectors
for (int i = 0; i < ctrl.checkedListBoxSectors.Items.Count; i++)
{
if(ctrl.checkedListBoxSectors.GetItemCheckState(i) == CheckState.Checked)
items.Add(i);
}
int useitem = items.Count - 1;
/*
Case 1: all tagged sectors are also selected sectors. In this case we can reuse
the original control, so one less additional control is needed
Case 2: multiple tagged sectors are also selected sectors. In this case we can
reuse the original control, so one less additional control is needed
Case 3: only one tagged sector is also the selected sector. In this case we
have to add exactly one additional control
*/
if (items.Count == 1)
numsplits = 1;
else
numsplits = items.Count - 1;
// Get new controls for the additional 3D floors
for (int i = 0; i < numsplits; i++)
{
var newctrl = GetThreeDFloorControl();
newctrl.Update(ctrl);
controls.Add(newctrl);
}
// Update the ckeckboxes of the controls to reflect the split 3D floors
for (int i = controls.Count - 1; i >= 0 ; i--)
{
// Uncheck all sectors...
for (int j = 0; j < items.Count; j++)
controls[i].checkedListBoxSectors.SetItemChecked(items[j], false);
// ... and only check a single one
if (useitem >= 0)
controls[i].checkedListBoxSectors.SetItemChecked(items[useitem], true);
useitem--;
}
// Show the new controls
foreach (Control c in controls)
c.Show();
}
public void DetachThreeDFloor(ThreeDFloorHelperControl ctrl)
{
ThreeDFloorHelperControl dup = GetThreeDFloorControl();
dup.Update(ctrl);
for (int i = 0; i < ctrl.checkedListBoxSectors.Items.Count; i++)
{
if (ctrl.checkedListBoxSectors.GetItemCheckState(i) == CheckState.Checked)
ctrl.checkedListBoxSectors.SetItemChecked(i, false);
}
dup.Show();
threeDFloorPanel.ScrollControlIntoView(dup);
}
private void FillThreeDFloorPanel(List<ThreeDFloor> threedfloors)
{
if (threedfloors.Count > 0)
{
// Create a new controller instance for each linedef and set its properties
foreach (ThreeDFloor tdf in threedfloors.OrderByDescending(o => o.TopHeight).ToList())
{
ThreeDFloorHelperControl ctrl = GetThreeDFloorControl();
ctrl.Update(tdf);
ctrl.Show();
}
no3dfloorspanel.Hide();
}
else
{
no3dfloorspanel.Show();
}
// Hide all unused pool controls
if (controlpool.Count - threedfloors.Count > 0)
{
foreach (ThreeDFloorHelperControl ctrl in controlpool.Skip(threedfloors.Count))
{
ctrl.Used = false;
ctrl.Hide();
}
}
}
private void sharedThreeDFloorsCheckBox_CheckedChanged(object sender, EventArgs e)
{
ICollection<Sector> selectedSectors = General.Map.Map.GetSelectedSectors(true);
if (selectedSectors.Count > 1 && sharedThreeDFloorsCheckBox.Checked)
{
var hideControls = new List<ThreeDFloorHelperControl>();
foreach (Sector s in selectedSectors)
{
foreach (ThreeDFloorHelperControl ctrl in threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>())
{
// If the selected sector is not in the control's tagged sectors the control
// should be hidden
if (!ctrl.ThreeDFloor.TaggedSectors.Contains(s))
hideControls.Add(ctrl);
}
}
foreach (ThreeDFloorHelperControl ctrl in hideControls)
{
// Hide controls, unless they are new
if (ctrl.IsNew == false)
ctrl.Hide();
}
}
else
{
foreach (ThreeDFloorHelperControl ctrl in threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>())
if (ctrl.Used)
ctrl.Show();
}
}
private void ThreeDFloorEditorWindow_FormClosed(object sender, FormClosedEventArgs e)
{
// Get rid of dummy sectors and makes all controls available
foreach (ThreeDFloorHelperControl ctrl in threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>().ToList())
{
if (ctrl.Sector != null)
ctrl.Sector.Dispose();
ctrl.Used = false;
}
General.Map.Map.Update();
}
private void detachAllButton_Click(object sender, EventArgs e)
{
List<ThreeDFloorHelperControl> controls = threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>().Where(o => o.Used).ToList();
foreach (ThreeDFloorHelperControl ctrl in controls)
DetachThreeDFloor(ctrl);
}
private void splitAllButton_Click(object sender, EventArgs e)
{
List<ThreeDFloorHelperControl> controls = threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>().Where(o => o.Used).ToList();
foreach (ThreeDFloorHelperControl ctrl in controls)
SplitThreeDFloor(ctrl);
}
private void checkAllButton_Click(object sender, EventArgs e)
{
List<ThreeDFloorHelperControl> controls = threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>().Where(o => o.Used).ToList();
foreach (ThreeDFloorHelperControl ctrl in controls)
{
for (int i = 0; i < ctrl.checkedListBoxSectors.Items.Count; i++)
{
ctrl.checkedListBoxSectors.SetItemChecked(i, true);
}
}
}
private void uncheckAllButton_Click(object sender, EventArgs e)
{
List<ThreeDFloorHelperControl> controls = threeDFloorPanel.Controls.OfType<ThreeDFloorHelperControl>().Where(o => o.Used).ToList();
foreach (ThreeDFloorHelperControl ctrl in controls)
{
for (int i = 0; i < ctrl.checkedListBoxSectors.Items.Count; i++)
{
ctrl.checkedListBoxSectors.SetItemChecked(i, false);
}
}
}
}
}