private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { SoundEnvironment se = e.UserState as SoundEnvironment; General.Interface.DisplayStatus(StatusType.Busy, "Updating sound environments (" + e.ProgressPercentage + "%)"); panel.AddSoundEnvironment(se); General.Interface.RedrawDisplay(); }
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(); } }
// This highlights a new item private void Highlight(Sector s) { // Set new highlight highlighted = s; highlightedsoundenvironment = null; if (highlighted != null) { foreach (SoundEnvironment se in BuilderPlug.Me.SoundEnvironments) { if (se.Sectors.Contains(highlighted)) { highlightedsoundenvironment = se; break; } } } panel.HighlightSoundEnvironment(highlightedsoundenvironment); }
public void DeleteItem() { // Anything to do? if (highlightedthing == null) { return; } // Make undo General.Map.UndoRedo.CreateUndo("Delete sound environment thing"); General.Interface.DisplayStatus(StatusType.Action, "Deleted a sound environment thing."); // Remove from current sound environment if (highlightedsoundenvironment != null && highlightedsoundenvironment.Things.Contains(highlightedthing)) { lock (highlightedsoundenvironment) { highlightedsoundenvironment.Things.Remove(highlightedthing); } } // Dispose highlighted thing General.Map.Map.BeginAddRemove(); highlightedthing.Dispose(); highlightedthing = null; General.Map.Map.EndAddRemove(); // Update cache values General.Map.IsChanged = true; General.Map.ThingsFilter.Update(); // Update sound environments UpdateData(); // Invoke a new mousemove so that the highlighted item updates highlightedsoundenvironment = null; OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, (int)mousepos.x, (int)mousepos.y, 0)); // Redraw screen General.Interface.RedrawDisplay(); }
//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; } } }
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); } }
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); }
public void UpdateSoundEnvironments(object sender, DoWorkEventArgs e) { List <Sector> sectorstocheck = new List <Sector>(); List <Sector> checkedsectors = new List <Sector>(); List <Sector> allsectors = new List <Sector>(); BackgroundWorker worker = sender as BackgroundWorker; List <FlatVertex> vertsList = new List <FlatVertex>(); Dictionary <Thing, PixelColor> secolor = new Dictionary <Thing, PixelColor>(); Dictionary <Thing, int> senumber = new Dictionary <Thing, int>(); soundenvironments.Clear(); blockinglinedefs.Clear(); SoundEnvironmentMode.SoundEnvironmentPanel.BeginUpdate(); //mxd // Keep track of all the sectors in the map. Sectors that belong to a sound environment // will be removed from the list, so in the end only sectors that don't belong to any // sound environment will be in this list foreach (Sector s in General.Map.Map.Sectors) { allsectors.Add(s); } List <Thing> soundenvironmenthings = GetSoundEnvironmentThings(General.Map.Map.Sectors.ToList()); int numthings = soundenvironmenthings.Count; // Assign each thing a color and a number, so each sound environment will always have the same color // and id, no matter in what order they are discovered for (int i = 0; i < soundenvironmenthings.Count; i++) { //mxd. Make sure same environments use the same color int seid = (soundenvironmenthings[i].Args[0] << 8) + soundenvironmenthings[i].Args[1]; secolor[soundenvironmenthings[i]] = distinctcolors[seid % distinctcolors.Count]; senumber.Add(soundenvironmenthings[i], i + 1); } while (soundenvironmenthings.Count > 0 && !worker.CancellationPending) { // Sort things by distance to center of the screen, so that sound environments the user want to look at will (hopefully) be discovered first Vector2D center = General.Map.Renderer2D.DisplayToMap(new Vector2D(General.Interface.Display.Width / 2f, General.Interface.Display.Height / 2f)); soundenvironmenthings = soundenvironmenthings.OrderBy(o => Math.Abs(Vector2D.Distance(center, o.Position))).ToList(); Thing thing = soundenvironmenthings[0]; if (thing.Sector == null) { thing.DetermineSector(); } // Ignore things that are outside the map if (thing.Sector == null) { soundenvironmenthings.Remove(thing); continue; } SoundEnvironment environment = new SoundEnvironment(); // Add initial sector. Additional adjacant sectors will be added later // as they are discovered sectorstocheck.Add(thing.Sector); while (sectorstocheck.Count > 0) { Sector sector = sectorstocheck[0]; if (!environment.Sectors.Contains(sector)) { environment.Sectors.Add(sector); } if (!checkedsectors.Contains(sector)) { checkedsectors.Add(sector); } sectorstocheck.Remove(sector); allsectors.Remove(sector); // Find adjacant sectors and add them to the list of sectors to check if necessary foreach (Sidedef sd in sector.Sidedefs) { if (LinedefBlocksSoundEnvironment(sd.Line)) { if (!environment.Linedefs.Contains(sd.Line)) { environment.Linedefs.Add(sd.Line); } continue; } if (sd.Other == null) { continue; } Sector oppositesector = (sd.Line.Front.Sector == sector ? sd.Line.Back.Sector : sd.Line.Front.Sector); if (!sectorstocheck.Contains(oppositesector) && !checkedsectors.Contains(oppositesector)) { sectorstocheck.Add(oppositesector); } } } // Get all things that are in the current sound environment... environment.Things = GetSoundEnvironmentThings(environment.Sectors); // ... and remove them from the list of sound environment things to check, because we know that // they already belong to a sound environment foreach (Thing t in environment.Things) { if (soundenvironmenthings.Contains(t)) { soundenvironmenthings.Remove(t); } } // Set color and id of the sound environment environment.Color = secolor[environment.Things[0]]; environment.ID = senumber[environment.Things[0]]; // Create the data for the overlay geometry List <FlatVertex> severtslist = new List <FlatVertex>(environment.Sectors.Count * 3); //mxd foreach (Sector s in environment.Sectors) { FlatVertex[] fv = new FlatVertex[s.FlatVertices.Length]; s.FlatVertices.CopyTo(fv, 0); for (int j = 0; j < fv.Length; j++) { fv[j].c = environment.Color.WithAlpha(128).ToInt(); } vertsList.AddRange(fv); severtslist.AddRange(fv); //mxd // Get all Linedefs that will block sound environments foreach (Sidedef sd in s.Sidedefs) { if (!LinedefBlocksSoundEnvironment(sd.Line)) { continue; } lock (blockinglinedefs) { blockinglinedefs.Add(sd.Line); } } } //mxd. Store sector environment verts environment.SectorsGeometry = severtslist.ToArray(); // Update the overlay geometry with the newly added sectors if (overlayGeometry == null) { overlayGeometry = vertsList.ToArray(); } else { lock (overlayGeometry) { overlayGeometry = vertsList.ToArray(); } } environment.Things = environment.Things.OrderBy(o => o.Index).ToList(); environment.Linedefs = environment.Linedefs.OrderBy(o => o.Index).ToList(); //mxd. Find the first non-dormant thing Thing activeenv = null; foreach (Thing t in environment.Things) { if (!ThingDormant(t)) { activeenv = t; break; } } //mxd. Update environment name if (activeenv != null) { foreach (KeyValuePair <string, KeyValuePair <int, int> > group in General.Map.Data.Reverbs) { if (group.Value.Key == activeenv.Args[0] && group.Value.Value == activeenv.Args[1]) { environment.Name = group.Key + " (" + activeenv.Args[0] + " " + activeenv.Args[1] + ")"; break; } } //mxd. No suitable name found?.. if (environment.Name == SoundEnvironment.DEFAULT_NAME) { environment.Name += " (" + activeenv.Args[0] + " " + activeenv.Args[1] + ")"; } } //mxd. Still no suitable name?.. if (environment.Name == SoundEnvironment.DEFAULT_NAME) { environment.Name += " " + environment.ID; } lock (soundenvironments) { soundenvironments.Add(environment); } // Tell the worker that discovering a sound environment is finished. This will update the tree view, and also // redraw the interface, so the sectors of this sound environment are colored worker.ReportProgress((int)((1.0f - (soundenvironmenthings.Count / (float)numthings)) * 100), environment); } // Create overlay geometry for sectors that don't belong to a sound environment foreach (Sector s in allsectors) { FlatVertex[] fv = new FlatVertex[s.FlatVertices.Length]; s.FlatVertices.CopyTo(fv, 0); for (int j = 0; j < fv.Length; j++) { fv[j].c = NoSoundColor.WithAlpha(128).ToInt(); } vertsList.AddRange(fv); } if (overlayGeometry == null) { overlayGeometry = vertsList.ToArray(); } else { lock (overlayGeometry) { overlayGeometry = vertsList.ToArray(); } } soundenvironmentisupdated = true; SoundEnvironmentMode.SoundEnvironmentPanel.EndUpdate(); //mxd }
// Mouse moves public override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); // Not holding any buttons? if (e.Button == MouseButtons.None) { General.Interface.SetCursor(Cursors.Default); // Find the nearest linedef within highlight range Linedef l = General.Map.Map.NearestLinedef(mousemappos); if (l != null) { // Check on which side of the linedef the mouse is float side = l.SideOfLine(mousemappos); if (side > 0) { // Is there a sidedef here? if (l.Back != null) { // Highlight if not the same if (l.Back.Sector != highlighted) { Highlight(l.Back.Sector); } } else if (highlighted != null) { // Highlight nothing Highlight(null); } } else { // Is there a sidedef here? if (l.Front != null) { // Highlight if not the same if (l.Front.Sector != highlighted) { Highlight(l.Front.Sector); } } else if (highlighted != null) { // Highlight nothing Highlight(null); } } } else if (highlighted != null) { // Highlight nothing Highlight(null); } //mxd. Find the nearest linedef within default highlight range l = General.Map.Map.NearestLinedefRange(mousemappos, 20 / renderer.Scale); //mxd. We are not interested in single-sided lines, unless they have zoneboundary flag... if (l != null && ((l.Front == null || l.Back == null) && !l.IsFlagSet(ZoneBoundaryFlag))) { l = null; } //mxd. Set as highlighted bool redrawrequired = false; if (highlightedline != l) { highlightedline = l; redrawrequired = true; } //mxd. Highlighted environment changed? if (oldhighlightedsoundenvironment != highlightedsoundenvironment) { oldhighlightedsoundenvironment = highlightedsoundenvironment; redrawrequired = true; } //mxd. Find the nearest thing within default highlight range if (highlightedline == null && highlightedsoundenvironment != null) { Thing t = MapSet.NearestThingSquareRange(highlightedsoundenvironment.Things, mousemappos, 10 / renderer.Scale); if (highlightedthing != t) { highlightedthing = t; redrawrequired = true; } } else if (highlightedthing != null) { highlightedthing = null; redrawrequired = true; } //mxd if (redrawrequired) { // Show highlight info if (highlightedline != null && !highlightedline.IsDisposed) { General.Interface.ShowLinedefInfo(highlightedline); } else if (highlighted != null && !highlighted.IsDisposed) { General.Interface.ShowSectorInfo(highlighted); } else { General.Interface.HideInfo(); } // Redraw display General.Interface.RedrawDisplay(); } } }