mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-27 14:12:16 +00:00
329 lines
9.3 KiB
C#
Executable file
329 lines
9.3 KiB
C#
Executable file
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using CodeImp.DoomBuilder.Controls;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using CodeImp.DoomBuilder.Editing;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
|
|
namespace CodeImp.DoomBuilder.SoundPropagationMode
|
|
{
|
|
public partial class SoundEnvironmentPanel : UserControl
|
|
{
|
|
public event EventHandler OnShowWarningsOnlyChanged; //mxd
|
|
public BufferedTreeView SoundEnvironments { get { return soundenvironments; } set { soundenvironments = value; } }
|
|
private readonly int warningiconindex; //mxd
|
|
private bool treeisupdating; //mxd
|
|
private int nodewarningscount; //mxd
|
|
private const string shownodewarningstext = "Show nodes with warnings only (N)";
|
|
private delegate void UpdateCallback(); //mxd
|
|
|
|
public SoundEnvironmentPanel()
|
|
{
|
|
InitializeComponent();
|
|
|
|
soundenvironments.ImageList = new ImageList();
|
|
foreach(Bitmap icon in BuilderPlug.Me.DistinctIcons)
|
|
{
|
|
soundenvironments.ImageList.Images.Add(icon);
|
|
}
|
|
soundenvironments.ImageList.Images.Add(Properties.Resources.Warning);
|
|
warningiconindex = soundenvironments.ImageList.Images.Count - 1; //mxd
|
|
}
|
|
|
|
//mxd
|
|
public void BeginUpdate()
|
|
{
|
|
if(treeisupdating) return;
|
|
|
|
if(soundenvironments.InvokeRequired)
|
|
{
|
|
UpdateCallback d = BeginUpdate;
|
|
soundenvironments.Invoke(d);
|
|
}
|
|
else
|
|
{
|
|
soundenvironments.BeginUpdate();
|
|
nodewarningscount = 0;
|
|
}
|
|
}
|
|
|
|
//mxd
|
|
public void EndUpdate()
|
|
{
|
|
if(soundenvironments.InvokeRequired)
|
|
{
|
|
UpdateCallback d = EndUpdate;
|
|
soundenvironments.Invoke(d);
|
|
}
|
|
else
|
|
{
|
|
treeisupdating = false;
|
|
soundenvironments.Sort();
|
|
soundenvironments.EndUpdate();
|
|
|
|
// Update the checkbox
|
|
showwarningsonly.Text = shownodewarningstext.Replace("(N)", "(" + nodewarningscount + ")");
|
|
showwarningsonly.Enabled = (showwarningsonly.Checked || nodewarningscount > 0);
|
|
}
|
|
}
|
|
|
|
public void AddSoundEnvironment(SoundEnvironment se)
|
|
{
|
|
TreeNode topnode = new TreeNode(se.Name);
|
|
topnode.Tag = se; //mxd
|
|
TreeNode thingsnode = new TreeNode("Things (" + se.Things.Count + ")");
|
|
TreeNode linedefsnode = new TreeNode("Linedefs (" + se.Linedefs.Count + ")");
|
|
int notdormant = 0;
|
|
int iconindex = BuilderPlug.Me.DistinctColors.IndexOf(se.Color); //mxd
|
|
int topindex = iconindex; //mxd
|
|
bool nodehaswarnings = false; //mxd
|
|
|
|
thingsnode.ImageIndex = iconindex; //mxd
|
|
thingsnode.SelectedImageIndex = iconindex; //mxd
|
|
linedefsnode.ImageIndex = iconindex; //mxd
|
|
linedefsnode.SelectedImageIndex = iconindex; //mxd
|
|
|
|
// Add things
|
|
foreach(Thing t in se.Things)
|
|
{
|
|
TreeNode thingnode = new TreeNode("Thing " + t.Index);
|
|
thingnode.Tag = t;
|
|
thingnode.ImageIndex = iconindex; //mxd
|
|
thingnode.SelectedImageIndex = iconindex; //mxd
|
|
thingsnode.Nodes.Add(thingnode);
|
|
|
|
if(!BuilderPlug.ThingDormant(t))
|
|
{
|
|
notdormant++;
|
|
}
|
|
else
|
|
{
|
|
thingnode.Text += " (dormant)";
|
|
}
|
|
}
|
|
|
|
// Set the icon to warning sign and add the tooltip when there are more than 1 non-dormant things
|
|
if(notdormant > 1)
|
|
{
|
|
thingsnode.ImageIndex = warningiconindex;
|
|
thingsnode.SelectedImageIndex = warningiconindex;
|
|
topindex = warningiconindex;
|
|
|
|
foreach(TreeNode tn in thingsnode.Nodes)
|
|
{
|
|
if(!BuilderPlug.ThingDormant((Thing)tn.Tag))
|
|
{
|
|
tn.ImageIndex = warningiconindex;
|
|
tn.SelectedImageIndex = warningiconindex;
|
|
tn.ToolTipText = "More than one thing in this\nsound environment is set to be\nactive. Set all but one thing\nto dormant.";
|
|
nodewarningscount++; //mxd
|
|
nodehaswarnings = true; //mxd
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add linedefs
|
|
foreach(Linedef ld in se.Linedefs)
|
|
{
|
|
bool showwarning = false;
|
|
TreeNode linedefnode = new TreeNode("Linedef " + ld.Index);
|
|
linedefnode.Tag = ld;
|
|
linedefnode.ImageIndex = iconindex; //mxd
|
|
linedefnode.SelectedImageIndex = iconindex; //mxd
|
|
|
|
if(ld.Back == null || ld.Front == null)
|
|
{
|
|
showwarning = true;
|
|
linedefnode.ToolTipText = "This line is single-sided, but has\nthe sound boundary flag set.";
|
|
}
|
|
else if(se.Sectors.Contains(ld.Front.Sector) && se.Sectors.Contains(ld.Back.Sector))
|
|
{
|
|
showwarning = true;
|
|
linedefnode.ToolTipText = "More than one thing in this\nThe sectors on both sides of\nthe line belong to the same\nsound environment.";
|
|
}
|
|
|
|
if(showwarning)
|
|
{
|
|
linedefnode.ImageIndex = warningiconindex;
|
|
linedefnode.SelectedImageIndex = warningiconindex;
|
|
|
|
linedefsnode.ImageIndex = warningiconindex;
|
|
linedefsnode.SelectedImageIndex = warningiconindex;
|
|
|
|
topindex = warningiconindex;
|
|
nodewarningscount++; //mxd
|
|
nodehaswarnings = true; //mxd
|
|
}
|
|
|
|
linedefsnode.Nodes.Add(linedefnode);
|
|
}
|
|
|
|
//mxd
|
|
if(!showwarningsonly.Checked || nodehaswarnings)
|
|
{
|
|
topnode.Nodes.Add(thingsnode);
|
|
topnode.Nodes.Add(linedefsnode);
|
|
|
|
topnode.Tag = se;
|
|
topnode.ImageIndex = topindex;
|
|
topnode.SelectedImageIndex = topindex;
|
|
|
|
// Sound environments will no be added in consecutive order, so we'll have to find
|
|
// out where in the tree to add the node
|
|
int insertionplace = 0;
|
|
|
|
foreach(TreeNode tn in soundenvironments.Nodes)
|
|
{
|
|
if(se.ID < ((SoundEnvironment)tn.Tag).ID) break;
|
|
insertionplace++;
|
|
}
|
|
|
|
soundenvironments.Nodes.Insert(insertionplace, topnode);
|
|
}
|
|
}
|
|
|
|
public void HighlightSoundEnvironment(SoundEnvironment se)
|
|
{
|
|
if(soundenvironments.SelectedNode != null) return; //mxd
|
|
if(!treeisupdating) soundenvironments.BeginUpdate();
|
|
soundenvironments.CollapseAll(); //mxd
|
|
|
|
foreach(TreeNode tn in soundenvironments.Nodes)
|
|
{
|
|
if(se != null && ((SoundEnvironment)tn.Tag).ID == se.ID)
|
|
{
|
|
if(tn.NodeFont == null || tn.NodeFont.Style != FontStyle.Bold)
|
|
tn.NodeFont = new Font(soundenvironments.Font.FontFamily, soundenvironments.Font.Size, FontStyle.Bold);
|
|
|
|
//mxd
|
|
tn.Expand();
|
|
if(soundenvironments.SelectedNode == null) tn.EnsureVisible();
|
|
}
|
|
else
|
|
{
|
|
if(tn.NodeFont == null || tn.NodeFont.Style != FontStyle.Regular)
|
|
tn.NodeFont = new Font(soundenvironments.Font.FontFamily, soundenvironments.Font.Size);
|
|
}
|
|
}
|
|
|
|
if(!treeisupdating) soundenvironments.EndUpdate();
|
|
}
|
|
|
|
//mxd. This (de)selects sound environment
|
|
public void SelectSoundEnvironment(SoundEnvironment se)
|
|
{
|
|
if((se == null && soundenvironments.SelectedNode != null) || (se != null && soundenvironments.SelectedNode != null && soundenvironments.SelectedNode.Tag is SoundEnvironment && ((SoundEnvironment)soundenvironments.SelectedNode.Tag).ID == se.ID))
|
|
{
|
|
soundenvironments.SelectedNode = null;
|
|
return;
|
|
}
|
|
|
|
if(se == null) return;
|
|
|
|
foreach(TreeNode tn in soundenvironments.Nodes)
|
|
{
|
|
if(((SoundEnvironment)tn.Tag).ID == se.ID)
|
|
{
|
|
soundenvironments.SelectedNode = tn;
|
|
tn.EnsureVisible();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool IsClickOnText(TreeView treeView, TreeNode node, Point location)
|
|
{
|
|
var hitTest = treeView.HitTest(location);
|
|
return hitTest.Node == node && (hitTest.Location == TreeViewHitTestLocations.Label || hitTest.Location == TreeViewHitTestLocations.Image);
|
|
}
|
|
|
|
private static void ProcessNodeClick(TreeNode node)
|
|
{
|
|
if(node == null) return;
|
|
|
|
List<Vector2D> points = new List<Vector2D>();
|
|
RectangleF area = MapSet.CreateEmptyArea();
|
|
|
|
if(node.Parent == null)
|
|
{
|
|
if(node.Tag is SoundEnvironment)
|
|
{
|
|
SoundEnvironment se = (SoundEnvironment)node.Tag;
|
|
|
|
foreach(Sector s in se.Sectors)
|
|
{
|
|
foreach(Sidedef sd in s.Sidedefs)
|
|
{
|
|
points.Add(sd.Line.Start.Position);
|
|
points.Add(sd.Line.End.Position);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Don't zoom if the wrong nodes are selected
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(node.Tag is Thing)
|
|
{
|
|
Thing t = (Thing)node.Tag;
|
|
|
|
// We don't want to be zoomed too closely, so add somepadding
|
|
points.Add(t.Position - 200);
|
|
points.Add(t.Position + 200);
|
|
}
|
|
else if(node.Tag is Linedef)
|
|
{
|
|
Linedef ld = (Linedef)node.Tag;
|
|
|
|
points.Add(ld.Start.Position);
|
|
points.Add(ld.End.Position);
|
|
}
|
|
else
|
|
{
|
|
// Don't zoom if the wrong nodes are selected
|
|
return;
|
|
}
|
|
}
|
|
|
|
area = MapSet.IncreaseArea(area, points);
|
|
|
|
// Add padding
|
|
area.Inflate(100f, 100f);
|
|
|
|
// Zoom to area
|
|
ClassicMode editmode = (General.Editing.Mode as ClassicMode);
|
|
editmode.CenterOnArea(area, 0.0f);
|
|
}
|
|
|
|
#region ================== Events
|
|
|
|
private void soundenvironments_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
|
|
{
|
|
if(IsClickOnText(soundenvironments, e.Node, e.Location))
|
|
{
|
|
ProcessNodeClick(e.Node);
|
|
}
|
|
}
|
|
|
|
private void soundenvironments_BeforeSelect(object sender, TreeViewCancelEventArgs e)
|
|
{
|
|
if(e.Action != TreeViewAction.ByMouse) return;
|
|
var position = soundenvironments.PointToClient(Cursor.Position);
|
|
e.Cancel = !IsClickOnText(soundenvironments, e.Node, position);
|
|
}
|
|
|
|
//mxd
|
|
private void showwarningsonly_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if(OnShowWarningsOnlyChanged != null) OnShowWarningsOnlyChanged(this, EventArgs.Empty);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|