diff --git a/Build/Configurations/Boom.cfg b/Build/Configurations/Boom.cfg index 28b1c73e..a958b14d 100644 --- a/Build/Configurations/Boom.cfg +++ b/Build/Configurations/Boom.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = true; @@ -360,7 +362,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Doom.cfg b/Build/Configurations/Doom.cfg index a26a168c..bdd72bf3 100644 --- a/Build/Configurations/Doom.cfg +++ b/Build/Configurations/Doom.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -310,7 +312,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Doom2.cfg b/Build/Configurations/Doom2.cfg index a047c8d6..56d3b9ca 100644 --- a/Build/Configurations/Doom2.cfg +++ b/Build/Configurations/Doom2.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -311,7 +313,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Edge.cfg b/Build/Configurations/Edge.cfg index 1f9c5c6f..e9a2be68 100644 --- a/Build/Configurations/Edge.cfg +++ b/Build/Configurations/Edge.cfg @@ -16,6 +16,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -367,7 +369,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = " Open Door (closes)"; 2 = " Walk Once - Open the Door"; 3 = " Walk Once - Close the Door"; diff --git a/Build/Configurations/Eternity.cfg b/Build/Configurations/Eternity.cfg index 1d18a652..f2b8eb38 100644 --- a/Build/Configurations/Eternity.cfg +++ b/Build/Configurations/Eternity.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = true; @@ -368,7 +370,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Heretic.cfg b/Build/Configurations/Heretic.cfg index 67e2df0c..61a6e21e 100644 --- a/Build/Configurations/Heretic.cfg +++ b/Build/Configurations/Heretic.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -335,7 +337,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Hexen.cfg b/Build/Configurations/Hexen.cfg index c88a5991..72537646 100644 --- a/Build/Configurations/Hexen.cfg +++ b/Build/Configurations/Hexen.cfg @@ -13,6 +13,8 @@ formatinterface = "HexenMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -353,7 +355,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 20 { diff --git a/Build/Configurations/Legacy.cfg b/Build/Configurations/Legacy.cfg index d52f0cce..4464418d 100644 --- a/Build/Configurations/Legacy.cfg +++ b/Build/Configurations/Legacy.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = true; @@ -345,7 +347,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Risen3D.cfg b/Build/Configurations/Risen3D.cfg index 84382c7a..4a49c4de 100644 --- a/Build/Configurations/Risen3D.cfg +++ b/Build/Configurations/Risen3D.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = true; @@ -377,7 +379,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Skulltag_Doom.cfg b/Build/Configurations/Skulltag_Doom.cfg index 12f415bd..314de695 100644 --- a/Build/Configurations/Skulltag_Doom.cfg +++ b/Build/Configurations/Skulltag_Doom.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = true; @@ -379,7 +381,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/Skulltag_DoomHexen.cfg b/Build/Configurations/Skulltag_DoomHexen.cfg index 8d3d1c56..ea995cdb 100644 --- a/Build/Configurations/Skulltag_DoomHexen.cfg +++ b/Build/Configurations/Skulltag_DoomHexen.cfg @@ -13,6 +13,8 @@ formatinterface = "HexenMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -381,7 +383,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 20 { diff --git a/Build/Configurations/Strife.cfg b/Build/Configurations/Strife.cfg index c7b5c9a4..43248442 100644 --- a/Build/Configurations/Strife.cfg +++ b/Build/Configurations/Strife.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -317,7 +319,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/UltDoom.cfg b/Build/Configurations/UltDoom.cfg index d4274ef7..ce630044 100644 --- a/Build/Configurations/UltDoom.cfg +++ b/Build/Configurations/UltDoom.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -311,7 +313,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/ZDoom_Doom.cfg b/Build/Configurations/ZDoom_Doom.cfg index 228e8df6..85e98f85 100644 --- a/Build/Configurations/ZDoom_Doom.cfg +++ b/Build/Configurations/ZDoom_Doom.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // Engine specific features mixtexturesflats = true; @@ -378,7 +380,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Build/Configurations/ZDoom_DoomHexen.cfg b/Build/Configurations/ZDoom_DoomHexen.cfg index 3ddbe54b..23f85083 100644 --- a/Build/Configurations/ZDoom_DoomHexen.cfg +++ b/Build/Configurations/ZDoom_DoomHexen.cfg @@ -13,6 +13,8 @@ formatinterface = "HexenMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -543,7 +545,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 20 { diff --git a/Build/Configurations/ZDoom_HereticHexen.cfg b/Build/Configurations/ZDoom_HereticHexen.cfg index f0004e4f..2e0f1d87 100644 --- a/Build/Configurations/ZDoom_HereticHexen.cfg +++ b/Build/Configurations/ZDoom_HereticHexen.cfg @@ -13,6 +13,8 @@ formatinterface = "HexenMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -536,7 +538,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 20 { diff --git a/Build/Configurations/ZDoom_Hexen.cfg b/Build/Configurations/ZDoom_Hexen.cfg index b089db2a..11cdd0c9 100644 --- a/Build/Configurations/ZDoom_Hexen.cfg +++ b/Build/Configurations/ZDoom_Hexen.cfg @@ -13,6 +13,8 @@ formatinterface = "HexenMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -381,7 +383,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 20 { diff --git a/Build/Configurations/ZDoom_StrifeHexen.cfg b/Build/Configurations/ZDoom_StrifeHexen.cfg index 6bd8c74b..0f27a46f 100644 --- a/Build/Configurations/ZDoom_StrifeHexen.cfg +++ b/Build/Configurations/ZDoom_StrifeHexen.cfg @@ -13,6 +13,8 @@ formatinterface = "HexenMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -542,7 +544,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 20 { diff --git a/Build/Configurations/jDoom.cfg b/Build/Configurations/jDoom.cfg index e09bc13f..143be1a6 100644 --- a/Build/Configurations/jDoom.cfg +++ b/Build/Configurations/jDoom.cfg @@ -13,6 +13,8 @@ formatinterface = "DoomMapSetIO"; // Special linedefs soundlinedefflags = 64; // See linedefflags +singlesidedflags = 1; // See linedefflags +doublesidedflags = 4; // See linedefflags // No generalized types generalizedlinedefs = false; @@ -333,7 +335,7 @@ linedefactivations // but hey, are you willing to reformat the linedef types for each config? linedeftypes { - 0 = " Normal"; + 0 = " None"; 1 = "DR Door Open Wait Close (also monsters)"; 2 = "W1 Door Open Stay"; 3 = "W1 Door Close Stay"; diff --git a/Resources/Icons/Folder.png b/Resources/Icons/Folder.png new file mode 100644 index 00000000..1d415fd6 Binary files /dev/null and b/Resources/Icons/Folder.png differ diff --git a/Resources/Icons/treeview.png b/Resources/Icons/treeview.png new file mode 100644 index 00000000..0bbd274f Binary files /dev/null and b/Resources/Icons/treeview.png differ diff --git a/Source/Builder.csproj b/Source/Builder.csproj index c3328978..f977d2e6 100644 --- a/Source/Builder.csproj +++ b/Source/Builder.csproj @@ -45,7 +45,11 @@ --> + + + + @@ -96,6 +100,18 @@ AboutForm.cs + + UserControl + + + ActionSelectorControl.cs + + + UserControl + + + CheckboxArrayControl.cs + UserControl @@ -130,6 +146,12 @@ ImageBrowser.cs + + Form + + + LinedefEditForm.cs + UserControl @@ -252,8 +274,10 @@ + + @@ -284,6 +308,8 @@ + + @@ -310,6 +336,14 @@ + + Designer + ActionSelectorControl.cs + + + Designer + CheckboxArrayControl.cs + Designer ColorControl.cs @@ -334,6 +368,10 @@ Designer ImageBrowser.cs + + Designer + LinedefEditForm.cs + Designer LinedefInfoPanel.cs diff --git a/Source/Config/GameConfiguration.cs b/Source/Config/GameConfiguration.cs index c9e0c569..e46bba06 100644 --- a/Source/Config/GameConfiguration.cs +++ b/Source/Config/GameConfiguration.cs @@ -47,6 +47,8 @@ namespace CodeImp.DoomBuilder.Config private float defaultflatscale; private string formatinterface; private int soundlinedefflags; + private int singlesidedflags; + private int doublesidedflags; private bool mixtexturesflats; // Map lumps @@ -60,6 +62,12 @@ namespace CodeImp.DoomBuilder.Config private List thingcategories; private Dictionary things; + // Linedefs + private Dictionary linedefflags; + private Dictionary linedefactions; + private List sortedlinedefactions; + private List actioncategories; + #endregion #region ================== Properties @@ -69,6 +77,8 @@ namespace CodeImp.DoomBuilder.Config public float DefaultFlatScale { get { return defaultflatscale; } } public string FormatInterface { get { return formatinterface; } } public int SoundLinedefFlags { get { return soundlinedefflags; } } + public int SingleSidedFlags { get { return singlesidedflags; } } + public int DoubleSidedFlags { get { return doublesidedflags; } } public bool MixTexturesFlats { get { return mixtexturesflats; } } // Map lumps @@ -82,6 +92,12 @@ namespace CodeImp.DoomBuilder.Config public List ThingCategories { get { return thingcategories; } } public ICollection Things { get { return things.Values; } } + // Linedefs + public IDictionary LinedefFlags { get { return linedefflags; } } + public IDictionary LinedefActions { get { return linedefactions; } } + public List SortedLinedefActions { get { return sortedlinedefactions; } } + public List ActionCategories { get { return actioncategories; } } + #endregion #region ================== Constructor / Disposer @@ -89,19 +105,22 @@ namespace CodeImp.DoomBuilder.Config // Constructor public GameConfiguration(Configuration cfg) { - IDictionary dic; - ThingCategory thingcat; - // Initialize this.cfg = cfg; this.thingcategories = new List(); this.things = new Dictionary(); + this.linedefflags = new Dictionary(); + this.linedefactions = new Dictionary(); + this.actioncategories = new List(); + this.sortedlinedefactions = new List(); // Read general settings defaulttexturescale = cfg.ReadSetting("defaulttexturescale", 1f); defaultflatscale = cfg.ReadSetting("defaultflatscale", 1f); formatinterface = cfg.ReadSetting("formatinterface", ""); soundlinedefflags = cfg.ReadSetting("soundlinedefflags", 0); + singlesidedflags = cfg.ReadSetting("singlesidedflags", 0); + doublesidedflags = cfg.ReadSetting("doublesidedflags", 0); mixtexturesflats = cfg.ReadSetting("mixtexturesflats", false); // Get map lumps @@ -111,6 +130,27 @@ namespace CodeImp.DoomBuilder.Config textureranges = cfg.ReadSetting("textures", new Hashtable()); flatranges = cfg.ReadSetting("flats", new Hashtable()); + // Things + LoadThingCategories(); + + // Linedefs + LoadLinedefFlags(); + LoadLinedefActions(); + + // We have no destructor + GC.SuppressFinalize(this); + } + + #endregion + + #region ================== Loading + + // Things and thing categories + private void LoadThingCategories() + { + IDictionary dic; + ThingCategory thingcat; + // Get thing categories dic = cfg.ReadSetting("thingtypes", new Hashtable()); foreach(DictionaryEntry de in dic) @@ -121,11 +161,100 @@ namespace CodeImp.DoomBuilder.Config // Add all thing in category to the big list foreach(ThingTypeInfo t in thingcat.Things) things.Add(t.Index, t); } + } + + // Linedef flags + private void LoadLinedefFlags() + { + IDictionary dic; + int bitflagscheck = 0; + int bitvalue; + + // Get linedef flags + dic = cfg.ReadSetting("linedefflags", new Hashtable()); + foreach(DictionaryEntry de in dic) + { + // Try paring the bit value + if(int.TryParse(de.Key.ToString(), + NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite, + CultureInfo.InvariantCulture, out bitvalue)) + { + // Check for conflict and add to list + if((bitvalue & bitflagscheck) == 0) + linedefflags.Add(bitvalue, de.Value.ToString()); + else + General.WriteLogLine("WARNING: Structure 'linedefflags' contains conflicting bit flag keys. Make sure all keys are unique integers and powers of 2!"); - // We have no destructor - GC.SuppressFinalize(this); + // Update bit flags checking value + bitflagscheck |= bitvalue; + } + else + { + General.WriteLogLine("WARNING: Structure 'linedefflags' contains invalid keys!"); + } + } } + // Linedef actions and action categories + private void LoadLinedefActions() + { + Dictionary cats = new Dictionary(); + IDictionary dic; + LinedefActionInfo ai; + LinedefActionCategory ac; + int actionnumber; + + // Get linedef actions + dic = cfg.ReadSetting("linedeftypes", new Hashtable()); + foreach(DictionaryEntry de in dic) + { + // Try paring the action number + if(int.TryParse(de.Key.ToString(), + NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite, + CultureInfo.InvariantCulture, out actionnumber)) + { + // Expanded type? + if(de.Value is IDictionary) + { + // Let the class constructure read it + ai = new LinedefActionInfo(actionnumber, cfg); + } + else + { + // We have all the information in one string (title/prefix only) + ai = new LinedefActionInfo(actionnumber, de.Value.ToString()); + } + + // Make or get a category + if(cats.ContainsKey(ai.Category)) + ac = cats[ai.Category]; + else + { + ac = new LinedefActionCategory(ai.Category); + cats.Add(ai.Category, ac); + } + + // Add action to category and sorted list + sortedlinedefactions.Add(ai); + ac.Add(ai); + } + else + { + General.WriteLogLine("WARNING: Structure 'linedeftypes' contains invalid keys!"); + } + } + + // Sort the actions list + sortedlinedefactions.Sort(); + + // Copy categories to final list + actioncategories.Clear(); + actioncategories.AddRange(cats.Values); + + // Sort the categories list + actioncategories.Sort(); + } + #endregion #region ================== Methods diff --git a/Source/Config/INumberedTitle.cs b/Source/Config/INumberedTitle.cs new file mode 100644 index 00000000..d2bbd7b7 --- /dev/null +++ b/Source/Config/INumberedTitle.cs @@ -0,0 +1,41 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * 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. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using CodeImp.DoomBuilder.IO; +using CodeImp.DoomBuilder.Data; +using System.IO; +using System.Diagnostics; +using System.Windows.Forms; +using CodeImp.DoomBuilder.Rendering; + +#endregion + +namespace CodeImp.DoomBuilder.Config +{ + public interface INumberedTitle + { + // Properties + int Index { get; } + string Title { get; } + } +} diff --git a/Source/Config/LinedefActionCategory.cs b/Source/Config/LinedefActionCategory.cs new file mode 100644 index 00000000..37320cca --- /dev/null +++ b/Source/Config/LinedefActionCategory.cs @@ -0,0 +1,108 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * 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. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using CodeImp.DoomBuilder.IO; +using CodeImp.DoomBuilder.Data; +using System.IO; +using System.Diagnostics; +using System.Windows.Forms; +using CodeImp.DoomBuilder.Rendering; + +#endregion + +namespace CodeImp.DoomBuilder.Config +{ + public class LinedefActionCategory : IDisposable, IComparable + { + #region ================== Constants + + #endregion + + #region ================== Variables + + // Category properties + private string name; + + // Actions + private List actions; + + // Disposing + private bool isdisposed = false; + + #endregion + + #region ================== Properties + + public string Name { get { return name; } } + public List Actions { get { return actions; } } + public bool IsDisposed { get { return isdisposed; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + public LinedefActionCategory(string name) + { + // Initialize + this.name = name; + this.actions = new List(); + + // We have no destructor + GC.SuppressFinalize(this); + } + + // Diposer + public void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + actions = null; + + // Done + isdisposed = true; + } + } + + #endregion + + #region ================== Methods + + // This adds an action to this category + public void Add(LinedefActionInfo a) + { + // Make it so. + actions.Add(a); + } + + // This compares against another action category + public int CompareTo(LinedefActionCategory other) + { + return string.Compare(this.name, other.name); + } + + #endregion + } +} diff --git a/Source/Config/LinedefActionInfo.cs b/Source/Config/LinedefActionInfo.cs new file mode 100644 index 00000000..d6c17bca --- /dev/null +++ b/Source/Config/LinedefActionInfo.cs @@ -0,0 +1,158 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * 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. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using CodeImp.DoomBuilder.IO; +using CodeImp.DoomBuilder.Data; +using System.IO; +using System.Diagnostics; +using System.Windows.Forms; +using CodeImp.DoomBuilder.Map; + +#endregion + +namespace CodeImp.DoomBuilder.Config +{ + public class LinedefActionInfo : INumberedTitle, IComparable + { + #region ================== Constants + + #endregion + + #region ================== Variables + + // Properties + private int index; + private string prefix; + private string category; + private string name; + private string title; + private string[] argtitle; + private TagType[] argtagtype; + + #endregion + + #region ================== Properties + + public int Index { get { return index; } } + public string Prefix { get { return prefix; } } + public string Category { get { return category; } } + public string Name { get { return name; } } + public string Title { get { return title; } } + public string[] ArgTitle { get { return argtitle; } } + public TagType[] ArgTagType { get { return argtagtype; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + public LinedefActionInfo(int index, string desc) + { + string[] parts; + int p = 0; + + // Initialize + this.index = index; + this.argtitle = new string[Linedef.NUM_ARGS]; + this.argtagtype = new TagType[Linedef.NUM_ARGS]; + + // Find the parts by splitting on spaces + parts = desc.Split(new char[] {' '}, 3); + if(parts.Length >= 3) this.prefix = parts[p++]; else this.prefix = ""; + if(parts.Length >= 2) this.category = parts[p++]; else this.category = "Unknown"; + if(parts.Length >= 1) this.name = this.category + " " + parts[p++]; else this.name = this.category; + this.name = this.name.Trim(); + this.title = this.prefix + " " + this.name; + this.title = this.title.Trim(); + + // No args/marks + for(int i = 0; i < Linedef.NUM_ARGS; i++) + { + this.argtitle[i] = ""; + this.argtagtype[i] = TagType.None; + } + + // We have no destructor + GC.SuppressFinalize(this); + } + + // Constructor + public LinedefActionInfo(int index, Configuration cfg) + { + string desc; + string[] parts; + int p = 0; + int argindex; + + // Initialize + this.index = index; + this.argtitle = new string[Linedef.NUM_ARGS]; + this.argtagtype = new TagType[Linedef.NUM_ARGS]; + + // Read description + desc = cfg.ReadSetting("linedeftypes." + index.ToString(CultureInfo.InvariantCulture) + ".title", " Unknown"); + + // Find the parts by splitting on spaces + parts = desc.Split(new char[] { ' ' }, 3); + if(parts.Length >= 3) this.prefix = parts[p++]; else this.prefix = ""; + if(parts.Length >= 2) this.category = parts[p++]; else this.category = "Unknown"; + if(parts.Length >= 1) this.name = this.category + " " + parts[p++]; else this.name = this.category; + this.name = this.name.Trim(); + this.title = this.prefix + " " + this.name; + this.title = this.title.Trim(); + + // Read the args and marks + for(int i = 0; i < Linedef.NUM_ARGS; i++) + { + argindex = i + 1; + this.argtitle[i] = cfg.ReadSetting("linedeftypes." + index.ToString(CultureInfo.InvariantCulture) + + ".arg" + argindex.ToString(CultureInfo.InvariantCulture), ""); + this.argtagtype[i] = (TagType)cfg.ReadSetting("linedeftypes." + index.ToString(CultureInfo.InvariantCulture) + + ".mark" + argindex.ToString(CultureInfo.InvariantCulture), (int)TagType.None); + } + + // We have no destructor + GC.SuppressFinalize(this); + } + + #endregion + + #region ================== Methods + + // This presents the item as string + public override string ToString() + { + return index + ": " + prefix + " " + title; + } + + // This compares against another action info + public int CompareTo(LinedefActionInfo other) + { + if(this.index < other.index) return -1; + else if(this.index > other.index) return 1; + else return 0; + } + + #endregion + } +} diff --git a/Source/Config/TagType.cs b/Source/Config/TagType.cs new file mode 100644 index 00000000..38ef313d --- /dev/null +++ b/Source/Config/TagType.cs @@ -0,0 +1,41 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * 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. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using CodeImp.DoomBuilder.IO; +using CodeImp.DoomBuilder.Data; +using System.IO; +using System.Diagnostics; +using System.Windows.Forms; + +#endregion + +namespace CodeImp.DoomBuilder.Config +{ + public enum TagType + { + None = 0, + Sector = 1, + Thing = 2, + Linedef = 3 // Implement this? + } +} diff --git a/Source/Editing/ClassicMode.cs b/Source/Editing/ClassicMode.cs index ef8bfdc3..f56911f6 100644 --- a/Source/Editing/ClassicMode.cs +++ b/Source/Editing/ClassicMode.cs @@ -343,8 +343,8 @@ namespace CodeImp.DoomBuilder.Editing if(e.Button == mousedragging) { // No longer dragging - mousedragging = MouseButtons.None; DragStop(e); + mousedragging = MouseButtons.None; } // Let the base class know diff --git a/Source/Editing/DragVerticesMode.cs b/Source/Editing/DragVerticesMode.cs index 74597405..d3cbc685 100644 --- a/Source/Editing/DragVerticesMode.cs +++ b/Source/Editing/DragVerticesMode.cs @@ -47,6 +47,9 @@ namespace CodeImp.DoomBuilder.Editing #region ================== Variables + // Mode to return to + private EditMode basemode; + // Mouse position on map where dragging started private Vector2D dragstartmappos; @@ -79,12 +82,13 @@ namespace CodeImp.DoomBuilder.Editing #region ================== Constructor / Disposer // Constructor to start dragging immediately - public DragVerticesMode(Vertex dragitem, Vector2D dragstartmappos) + public DragVerticesMode(EditMode basemode, Vertex dragitem, Vector2D dragstartmappos) { // Initialize this.dragitem = dragitem; this.dragstartmappos = dragstartmappos; - + this.basemode = basemode; + Cursor.Current = Cursors.AppStarting; // Make list of selected vertices @@ -208,7 +212,7 @@ namespace CodeImp.DoomBuilder.Editing base.Cancel(); // Return to vertices mode - General.Map.ChangeMode(new VerticesMode()); + General.Map.ChangeMode(basemode); } // Mode engages @@ -223,12 +227,6 @@ namespace CodeImp.DoomBuilder.Editing // Disenagaging public override void Disengage() { - ICollection movinglines; - ICollection fixedlines; - Rectangle editarea; - int stitches = 0; - int stitchundo; - base.Disengage(); Cursor.Current = Cursors.AppStarting; @@ -244,47 +242,8 @@ namespace CodeImp.DoomBuilder.Editing // Move selected geometry to final position MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptonearest); - // ===== BEGIN GEOMETRY STITCHING - if(General.MainWindow.AutoMerge) - { - // Make undo for the stitching - stitchundo = General.Map.UndoRedo.CreateUndo("stitch geometry", UndoGroup.None, 0, false); - - // Find lines that moved during the drag - movinglines = General.Map.Map.LinedefsFromSelectedVertices(false, true, true); - - // Find all non-moving lines - fixedlines = General.Map.Map.LinedefsFromSelectedVertices(true, false, false); - - // Determine area in which we are editing - editarea = MapSet.AreaFromLines(movinglines); - editarea.Inflate((int)Math.Ceiling(General.Settings.StitchDistance), - (int)Math.Ceiling(General.Settings.StitchDistance)); - - // Join nearby vertices - stitches += MapSet.JoinVertices(unselectedverts, selectedverts, true, General.Settings.StitchDistance); - - // Update cached values - General.Map.Map.Update(); - - // Split moving lines with unselected vertices - unselectedverts = MapSet.FilterArea(unselectedverts, ref editarea); - stitches += MapSet.SplitLinesByVertices(movinglines, unselectedverts, General.Settings.StitchDistance, movinglines); - - // Split non-moving lines with selected vertices - fixedlines = MapSet.FilterArea(fixedlines, ref editarea); - stitches += MapSet.SplitLinesByVertices(fixedlines, selectedverts, General.Settings.StitchDistance, movinglines); - - // Remove looped linedefs - stitches += MapSet.RemoveLoopedLinedefs(movinglines); - - // Join overlapping lines - stitches += MapSet.JoinOverlappingLines(movinglines); - - // No stitching done? then withdraw undo - if(stitches == 0) General.Map.UndoRedo.WithdrawUndo(stitchundo); - } - // ===== END GEOMETRY STITCHING + // Stitch geometry + General.Map.Map.StitchGeometry(selectedverts, unselectedverts); // If only a single vertex was selected, deselect it now if(selectedverts.Count == 1) General.Map.Map.ClearSelectedVertices(); @@ -358,7 +317,7 @@ namespace CodeImp.DoomBuilder.Editing if(e.Button == EditMode.EDIT_BUTTON) { // Just return to vertices mode, geometry will be merged on disengage. - General.Map.ChangeMode(new VerticesMode()); + General.Map.ChangeMode(basemode); } } diff --git a/Source/Editing/LinedefsMode.cs b/Source/Editing/LinedefsMode.cs index 10a283df..9822e0e7 100644 --- a/Source/Editing/LinedefsMode.cs +++ b/Source/Editing/LinedefsMode.cs @@ -100,6 +100,22 @@ namespace CodeImp.DoomBuilder.Editing { base.Disengage(); + // Check which mode we are switching to + if(General.Map.NewMode is VerticesMode) + { + // Convert selection to vertices + + // Clear selected linedefs + General.Map.Map.ClearSelectedLinedefs(); + } + else if(General.Map.NewMode is SectorsMode) + { + // Convert selection to sectors + + // Clear selected linedefs + General.Map.Map.ClearSelectedLinedefs(); + } + // Hide highlight info General.MainWindow.HideInfo(); @@ -121,7 +137,7 @@ namespace CodeImp.DoomBuilder.Editing renderer.RenderLinedefSet(General.Map.Map.Linedefs); // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderLinedef(highlighted, General.Colors.Highlight); // Render vertices @@ -139,7 +155,7 @@ namespace CodeImp.DoomBuilder.Editing if(renderer.Start(false, false)) { // Undraw previous highlight - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) { renderer.RenderLinedef(highlighted, renderer.DetermineLinedefColor(highlighted)); renderer.RenderVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); @@ -150,7 +166,7 @@ namespace CodeImp.DoomBuilder.Editing highlighted = l; // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) { renderer.RenderLinedef(highlighted, General.Colors.Highlight); renderer.RenderVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); @@ -162,8 +178,10 @@ namespace CodeImp.DoomBuilder.Editing } // Show highlight info - if(highlighted != null) General.MainWindow.ShowLinedefInfo(highlighted); - else General.MainWindow.HideInfo(); + if((highlighted != null) && !highlighted.IsDisposed) + General.MainWindow.ShowLinedefInfo(highlighted); + else + General.MainWindow.HideInfo(); } // Mouse moves @@ -187,6 +205,102 @@ namespace CodeImp.DoomBuilder.Editing Highlight(null); } + // Mouse button pressed + public override void MouseDown(MouseEventArgs e) + { + base.MouseDown(e); + + // Select button? + if(e.Button == EditMode.SELECT_BUTTON) + { + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Flip selection + highlighted.Selected = !highlighted.Selected; + + // Update display + if(renderer.Start(false, false)) + { + // Redraw highlight to show selection + renderer.RenderLinedef(highlighted, renderer.DetermineLinedefColor(highlighted)); + renderer.RenderVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); + renderer.RenderVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End)); + renderer.Finish(); + } + } + } + // Edit button? + else if(e.Button == EditMode.EDIT_BUTTON) + { + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Highlighted item not selected? + if(!highlighted.Selected) + { + // Make this the only selection + General.Map.Map.ClearSelectedLinedefs(); + highlighted.Selected = true; + General.MainWindow.RedrawDisplay(); + } + + // Update display + if(renderer.Start(false, false)) + { + // Redraw highlight to show selection + renderer.RenderLinedef(highlighted, renderer.DetermineLinedefColor(highlighted)); + renderer.RenderVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); + renderer.RenderVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End)); + renderer.Finish(); + } + } + } + } + + // Mouse released + public override void MouseUp(MouseEventArgs e) + { + ICollection selected; + + base.MouseUp(e); + + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Update display + if(renderer.Start(false, false)) + { + // Render highlighted item + renderer.RenderLinedef(highlighted, General.Colors.Highlight); + renderer.RenderVertex(highlighted.Start, renderer.DetermineVertexColor(highlighted.Start)); + renderer.RenderVertex(highlighted.End, renderer.DetermineVertexColor(highlighted.End)); + renderer.Finish(); + } + + // Edit button? + if(e.Button == EditMode.EDIT_BUTTON) + { + // Anything selected? + selected = General.Map.Map.GetLinedefsSelection(true); + if(selected.Count > 0) + { + // Show line edit dialog + LinedefEditForm f = new LinedefEditForm(); + f.Setup(selected); + f.ShowDialog(General.MainWindow); + f.Dispose(); + + // When a single line was selected, deselect it now + if(selected.Count == 1) General.Map.Map.ClearSelectedLinedefs(); + + // Update entire display + General.MainWindow.RedrawDisplay(); + } + } + } + } + #endregion } } diff --git a/Source/Editing/SectorsMode.cs b/Source/Editing/SectorsMode.cs index 02ea8690..77e6a4d5 100644 --- a/Source/Editing/SectorsMode.cs +++ b/Source/Editing/SectorsMode.cs @@ -98,6 +98,22 @@ namespace CodeImp.DoomBuilder.Editing { base.Disengage(); + // Check which mode we are switching to + if(General.Map.NewMode is VerticesMode) + { + // Convert selection to vertices + + // Clear selected sectors + General.Map.Map.ClearSelectedSectors(); + } + else if(General.Map.NewMode is LinedefsMode) + { + // Convert selection to linedefs + + // Clear selected sectors + General.Map.Map.ClearSelectedSectors(); + } + // Hide highlight info General.MainWindow.HideInfo(); @@ -120,7 +136,7 @@ namespace CodeImp.DoomBuilder.Editing renderer.RenderVerticesSet(General.Map.Map.Vertices); // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderSector(highlighted, General.Colors.Highlight); // Done @@ -135,7 +151,7 @@ namespace CodeImp.DoomBuilder.Editing if(renderer.Start(false, false)) { // Undraw previous highlight - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderSector(highlighted); /* @@ -149,7 +165,7 @@ namespace CodeImp.DoomBuilder.Editing highlighted = s; // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderSector(highlighted, General.Colors.Highlight); /* @@ -164,8 +180,10 @@ namespace CodeImp.DoomBuilder.Editing } // Show highlight info - if(highlighted != null) General.MainWindow.ShowSectorInfo(highlighted); - else General.MainWindow.HideInfo(); + if((highlighted != null) && !highlighted.IsDisposed) + General.MainWindow.ShowSectorInfo(highlighted); + else + General.MainWindow.HideInfo(); } // Mouse moves @@ -217,6 +235,58 @@ namespace CodeImp.DoomBuilder.Editing Highlight(null); } + // Mouse button pressed + public override void MouseDown(MouseEventArgs e) + { + base.MouseDown(e); + bool front, back; + + // Which button is used? + if(e.Button == EditMode.SELECT_BUTTON) + { + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Flip selection + highlighted.Selected = !highlighted.Selected; + + // Make update lines selection + foreach(Sidedef sd in highlighted.Sidedefs) + { + if(sd.Line.Front != null) front = sd.Line.Front.Sector.Selected; else front = false; + if(sd.Line.Back != null) back = sd.Line.Back.Sector.Selected; else back = false; + sd.Line.Selected = front | back; + } + + // Update display + if(renderer.Start(false, false)) + { + // Redraw highlight to show selection + renderer.RenderSector(highlighted); + renderer.Finish(); + } + } + } + } + + // Mouse released + public override void MouseUp(MouseEventArgs e) + { + base.MouseUp(e); + + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Update display + if(renderer.Start(false, false)) + { + // Render highlighted item + renderer.RenderSector(highlighted, General.Colors.Highlight); + renderer.Finish(); + } + } + } + #endregion } } diff --git a/Source/Editing/ThingsMode.cs b/Source/Editing/ThingsMode.cs index 4b561f90..9b3e8074 100644 --- a/Source/Editing/ThingsMode.cs +++ b/Source/Editing/ThingsMode.cs @@ -122,7 +122,7 @@ namespace CodeImp.DoomBuilder.Editing renderer.RenderThingSet(General.Map.Map.Things); // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderThing(highlighted, General.Colors.Highlight); // Done @@ -137,14 +137,14 @@ namespace CodeImp.DoomBuilder.Editing if(renderer.Start(false, false)) { // Undraw previous highlight - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted)); // Set new highlight highlighted = t; // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderThing(highlighted, General.Colors.Highlight); // Done @@ -152,8 +152,10 @@ namespace CodeImp.DoomBuilder.Editing } // Show highlight info - if(highlighted != null) General.MainWindow.ShowThingInfo(highlighted); - else General.MainWindow.HideInfo(); + if((highlighted != null) && !highlighted.IsDisposed) + General.MainWindow.ShowThingInfo(highlighted); + else + General.MainWindow.HideInfo(); } // Mouse moves @@ -177,6 +179,92 @@ namespace CodeImp.DoomBuilder.Editing Highlight(null); } + // Mouse button pressed + public override void MouseDown(MouseEventArgs e) + { + base.MouseDown(e); + + // Select button? + if(e.Button == EditMode.SELECT_BUTTON) + { + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Flip selection + highlighted.Selected = !highlighted.Selected; + + // Update display + if(renderer.Start(false, false)) + { + // Redraw highlight to show selection + renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted)); + renderer.Finish(); + } + } + } + // Edit button? + else if(e.Button == EditMode.EDIT_BUTTON) + { + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Highlighted item not selected? + if(!highlighted.Selected) + { + // Make this the only selection + General.Map.Map.ClearSelectedThings(); + highlighted.Selected = true; + General.MainWindow.RedrawDisplay(); + } + + // Update display + if(renderer.Start(false, false)) + { + // Redraw highlight to show selection + renderer.RenderThing(highlighted, renderer.DetermineThingColor(highlighted)); + renderer.Finish(); + } + } + } + } + + // Mouse released + public override void MouseUp(MouseEventArgs e) + { + ICollection selected; + + base.MouseUp(e); + + // Item highlighted? + if((highlighted != null) && !highlighted.IsDisposed) + { + // Update display + if(renderer.Start(false, false)) + { + // Render highlighted item + renderer.RenderThing(highlighted, General.Colors.Highlight); + renderer.Finish(); + } + + // Edit button? + if(e.Button == EditMode.EDIT_BUTTON) + { + // Anything selected? + selected = General.Map.Map.GetThingsSelection(true); + if(selected.Count > 0) + { + // Show thing edit dialog + + // When a single thing was selected, deselect it now + if(selected.Count == 1) General.Map.Map.ClearSelectedThings(); + + // Update entire display + General.MainWindow.RedrawDisplay(); + } + } + } + } + #endregion } } diff --git a/Source/Editing/VerticesMode.cs b/Source/Editing/VerticesMode.cs index 750fc2ae..38f2aa12 100644 --- a/Source/Editing/VerticesMode.cs +++ b/Source/Editing/VerticesMode.cs @@ -100,6 +100,22 @@ namespace CodeImp.DoomBuilder.Editing { base.Disengage(); + // Check which mode we are switching to + if(General.Map.NewMode is LinedefsMode) + { + // Convert selection to linedefs + + // Clear selected vertices + General.Map.Map.ClearSelectedVertices(); + } + else if(General.Map.NewMode is SectorsMode) + { + // Convert selection to sectors + + // Clear selected vertices + General.Map.Map.ClearSelectedVertices(); + } + // Hide highlight info General.MainWindow.HideInfo(); @@ -122,7 +138,7 @@ namespace CodeImp.DoomBuilder.Editing renderer.RenderVerticesSet(General.Map.Map.Vertices); // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderVertex(highlighted, ColorCollection.HIGHLIGHT); // Done @@ -137,14 +153,14 @@ namespace CodeImp.DoomBuilder.Editing if(renderer.Start(false, false)) { // Undraw previous highlight - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderVertex(highlighted, renderer.DetermineVertexColor(highlighted)); // Set new highlight highlighted = v; // Render highlighted item - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) renderer.RenderVertex(highlighted, ColorCollection.HIGHLIGHT); // Done @@ -152,8 +168,10 @@ namespace CodeImp.DoomBuilder.Editing } // Show highlight info - if(highlighted != null) General.MainWindow.ShowVertexInfo(highlighted); - else General.MainWindow.HideInfo(); + if((highlighted != null) && !highlighted.IsDisposed) + General.MainWindow.ShowVertexInfo(highlighted); + else + General.MainWindow.HideInfo(); } // Mouse moves @@ -190,7 +208,7 @@ namespace CodeImp.DoomBuilder.Editing if(e.Button == EditMode.SELECT_BUTTON) { // Item highlighted? - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) { // Flip selection highlighted.Selected = !highlighted.Selected; @@ -198,7 +216,7 @@ namespace CodeImp.DoomBuilder.Editing // Update display if(renderer.Start(false, false)) { - // Undraw highlight to show selection + // Redraw highlight to show selection renderer.RenderVertex(highlighted, renderer.DetermineVertexColor(highlighted)); renderer.Finish(); } @@ -212,7 +230,7 @@ namespace CodeImp.DoomBuilder.Editing base.MouseUp(e); // Item highlighted? - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) { // Update display if(renderer.Start(false, false)) @@ -238,7 +256,7 @@ namespace CodeImp.DoomBuilder.Editing else if(e.Button == EditMode.EDIT_BUTTON) { // Anything highlighted? - if(highlighted != null) + if((highlighted != null) && !highlighted.IsDisposed) { // Highlighted item not selected? if(!highlighted.Selected) @@ -249,10 +267,11 @@ namespace CodeImp.DoomBuilder.Editing } // Start dragging the selection - General.Map.ChangeMode(new DragVerticesMode(highlighted, mousedownmappos)); + General.Map.ChangeMode(new DragVerticesMode(new VerticesMode(), highlighted, mousedownmappos)); } } } + #endregion } } diff --git a/Source/General/General.cs b/Source/General/General.cs index 9877df97..39f8c444 100644 --- a/Source/General/General.cs +++ b/Source/General/General.cs @@ -777,6 +777,14 @@ namespace CodeImp.DoomBuilder #region ================== Tools + // This returns an element from a collection by index + public static T GetByIndex(ICollection collection, int index) + { + IEnumerator e = collection.GetEnumerator(); + for(int i = -1; i < index; i++) e.MoveNext(); + return e.Current; + } + // This returns the next power of 2 public static int NextPowerOf2(int v) { diff --git a/Source/General/MapManager.cs b/Source/General/MapManager.cs index 16628482..3c9e4c43 100644 --- a/Source/General/MapManager.cs +++ b/Source/General/MapManager.cs @@ -71,6 +71,7 @@ namespace CodeImp.DoomBuilder private GameConfiguration config; private DataManager data; private EditMode mode; + private EditMode newmode; private D3DDevice graphics; private Renderer2D renderer2d; private Renderer3D renderer3d; @@ -91,6 +92,7 @@ namespace CodeImp.DoomBuilder public MapOptions Options { get { return options; } } public MapSet Map { get { return map; } } public EditMode Mode { get { return mode; } } + public EditMode NewMode { get { return newmode; } } public DataManager Data { get { return data; } } public bool IsChanged { get { return changed; } set { changed |= value; } } public bool IsDisposed { get { return isdisposed; } } @@ -825,10 +827,11 @@ namespace CodeImp.DoomBuilder // - Engage of new mode is called // - Dispose of old mode is called // - public void ChangeMode(EditMode newmode) + public void ChangeMode(EditMode nextmode) { EditMode oldmode = mode; - + newmode = nextmode; + // Log info if(newmode != null) General.WriteLogLine("Switching edit mode to " + newmode.GetType().Name + "..."); @@ -847,6 +850,9 @@ namespace CodeImp.DoomBuilder // Dispose old mode if(mode != null) mode.Dispose(); + // Done switching + newmode = null; + // Redraw the display General.MainWindow.RedrawDisplay(); } diff --git a/Source/Interface/ActionSelectorControl.Designer.cs b/Source/Interface/ActionSelectorControl.Designer.cs new file mode 100644 index 00000000..2f299f95 --- /dev/null +++ b/Source/Interface/ActionSelectorControl.Designer.cs @@ -0,0 +1,98 @@ +namespace CodeImp.DoomBuilder.Interface +{ + partial class ActionSelectorControl + { + /// + /// 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 Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.number = new System.Windows.Forms.TextBox(); + this.list = new System.Windows.Forms.ComboBox(); + this.numberpanel = new System.Windows.Forms.Panel(); + this.numberpanel.SuspendLayout(); + this.SuspendLayout(); + // + // number + // + this.number.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.number.Location = new System.Drawing.Point(3, 1); + this.number.Name = "number"; + this.number.Size = new System.Drawing.Size(43, 13); + this.number.TabIndex = 0; + this.number.Text = "402"; + this.number.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.number.TextChanged += new System.EventHandler(this.number_TextChanged); + this.number.KeyDown += new System.Windows.Forms.KeyEventHandler(this.number_KeyDown); + // + // list + // + this.list.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; + this.list.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.list.FormattingEnabled = true; + this.list.IntegralHeight = false; + this.list.Location = new System.Drawing.Point(57, 0); + this.list.MaxDropDownItems = 15; + this.list.Name = "list"; + this.list.Size = new System.Drawing.Size(251, 21); + this.list.TabIndex = 2; + this.list.TabStop = false; + this.list.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.list_DrawItem); + this.list.SelectionChangeCommitted += new System.EventHandler(this.list_SelectionChangeCommitted); + this.list.DropDownClosed += new System.EventHandler(this.list_DropDownClosed); + // + // numberpanel + // + this.numberpanel.BackColor = System.Drawing.SystemColors.Window; + this.numberpanel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.numberpanel.Controls.Add(this.number); + this.numberpanel.Location = new System.Drawing.Point(0, 0); + this.numberpanel.Name = "numberpanel"; + this.numberpanel.Size = new System.Drawing.Size(53, 21); + this.numberpanel.TabIndex = 3; + // + // ActionSelectorControl + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.BackColor = System.Drawing.SystemColors.Control; + this.Controls.Add(this.numberpanel); + this.Controls.Add(this.list); + this.Cursor = System.Windows.Forms.Cursors.Default; + this.Name = "ActionSelectorControl"; + this.Size = new System.Drawing.Size(382, 21); + this.Layout += new System.Windows.Forms.LayoutEventHandler(this.ActionSelectorControl_Layout); + this.Resize += new System.EventHandler(this.ActionSelectorControl_Resize); + this.numberpanel.ResumeLayout(false); + this.numberpanel.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TextBox number; + private System.Windows.Forms.ComboBox list; + private System.Windows.Forms.Panel numberpanel; + } +} diff --git a/Source/Interface/ActionSelectorControl.cs b/Source/Interface/ActionSelectorControl.cs new file mode 100644 index 00000000..cf37d3ab --- /dev/null +++ b/Source/Interface/ActionSelectorControl.cs @@ -0,0 +1,193 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * 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. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using Microsoft.Win32; +using System.Drawing.Drawing2D; +using CodeImp.DoomBuilder.Config; + +#endregion + +namespace CodeImp.DoomBuilder.Interface +{ + public partial class ActionSelectorControl : UserControl + { + // Constants + private const string NUMBER_SEPERATOR = ":\t"; + + // Properties + public bool Empty { get { return (number.Text.Length == 0); } set { if(value) number.Text = ""; } } + public int Value { get { if(number.Text.Length > 0) return int.Parse(number.Text); else return 0; } set { number.Text = value.ToString(); } } + + // Constructor + public ActionSelectorControl() + { + // Initialize + InitializeComponent(); + } + + // This adds information to display + public void AddInfo(INumberedTitle[] infolist) + { + // Add to list + list.Items.AddRange(infolist); + } + + // Resized + private void ActionSelectorControl_Resize(object sender, EventArgs e) + { + list.Width = ClientRectangle.Width - list.Left; + ClientSize = new Size(ClientSize.Width, list.Height); + } + + // Layout change + private void ActionSelectorControl_Layout(object sender, LayoutEventArgs e) + { + ActionSelectorControl_Resize(sender, e); + } + + // This draws an item in the combobox + private void list_DrawItem(object sender, DrawItemEventArgs e) + { + INumberedTitle item; + Brush displaybrush; + Brush backbrush; + string displayname; + + // Unknow item? + if(e.Index < 0) + { + // Grayed + displaybrush = new SolidBrush(SystemColors.GrayText); + backbrush = new SolidBrush(SystemColors.Window); + + // Check what to display + if(number.Text.Length == 0) + displayname = ""; + else if(number.Text == "0") + displayname = "None"; + else + displayname = "Unknown"; + } + // In the display part of the combobox? + else if((e.State & DrawItemState.ComboBoxEdit) != 0) + { + // Show without number + item = (INumberedTitle)list.Items[e.Index]; + displayname = item.Title.Trim(); + + // Determine colors to use + if(item.Index == 0) + { + // Grayed + displaybrush = new SolidBrush(SystemColors.GrayText); + backbrush = new SolidBrush(SystemColors.Window); + } + else + { + // Normal color + displaybrush = new SolidBrush(list.ForeColor); + backbrush = new SolidBrush(SystemColors.Window); + } + } + else + { + // Use number and description + item = (INumberedTitle)list.Items[e.Index]; + displayname = item.Index + NUMBER_SEPERATOR + item.Title; + + // Determine colors to use + if((e.State & DrawItemState.Focus) != 0) + { + displaybrush = new SolidBrush(SystemColors.HighlightText); + backbrush = new SolidBrush(SystemColors.Highlight); + } + else + { + displaybrush = new SolidBrush(list.ForeColor); + backbrush = new SolidBrush(SystemColors.Window); + } + } + + // Draw item + e.Graphics.FillRectangle(backbrush, e.Bounds); + e.Graphics.DrawString(displayname, list.Font, displaybrush, e.Bounds.X, e.Bounds.Y); + } + + // List closed + private void list_DropDownClosed(object sender, EventArgs e) + { + // Focus to number box + number.SelectAll(); + number.Focus(); + } + + // Number changes + private void number_TextChanged(object sender, EventArgs e) + { + int itemindex = -1; + INumberedTitle item; + + // Not nothing? + if(number.Text.Length > 0) + { + // Find the index in the list + for(int i = 0; i < list.Items.Count; i++) + { + // This is the item we're looking for? + item = (INumberedTitle)list.Items[i]; + if(item.Index.ToString() == number.Text) + { + // Found it + itemindex = i; + break; + } + } + } + + // Select item + if(list.SelectedIndex != itemindex) list.SelectedIndex = itemindex; + list.Refresh(); + } + + // Keys pressed in number box + private void number_KeyDown(object sender, KeyEventArgs e) + { + // Not numeric or control key? + if(((e.KeyValue < 48) || (e.KeyValue > 57)) && + (e.KeyCode != Keys.Back) && (e.KeyCode != Keys.Left) && + (e.KeyCode != Keys.Right) && (e.KeyCode != Keys.Delete)) + { + // Cancel this + e.Handled = true; + } + } + + // Selection made + private void list_SelectionChangeCommitted(object sender, EventArgs e) + { + INumberedTitle item = (INumberedTitle)list.SelectedItem; + number.Text = item.Index.ToString(); + } + } +} diff --git a/Source/Interface/ActionSelectorControl.resx b/Source/Interface/ActionSelectorControl.resx new file mode 100644 index 00000000..b6517989 --- /dev/null +++ b/Source/Interface/ActionSelectorControl.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/Source/Interface/CheckboxArrayControl.Designer.cs b/Source/Interface/CheckboxArrayControl.Designer.cs new file mode 100644 index 00000000..2006ff06 --- /dev/null +++ b/Source/Interface/CheckboxArrayControl.Designer.cs @@ -0,0 +1,51 @@ +namespace CodeImp.DoomBuilder.Interface +{ + partial class CheckboxArrayControl + { + /// + /// 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 Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // CheckboxArrayControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScroll = true; + this.DoubleBuffered = true; + this.Name = "CheckboxArrayControl"; + this.Size = new System.Drawing.Size(361, 163); + this.Layout += new System.Windows.Forms.LayoutEventHandler(this.CheckboxArrayControl_Layout); + this.Paint += new System.Windows.Forms.PaintEventHandler(this.CheckboxArrayControl_Paint); + this.ResumeLayout(false); + + } + + #endregion + + + } +} diff --git a/Source/Interface/CheckboxArrayControl.cs b/Source/Interface/CheckboxArrayControl.cs new file mode 100644 index 00000000..8bb04f21 --- /dev/null +++ b/Source/Interface/CheckboxArrayControl.cs @@ -0,0 +1,135 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * 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. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using Microsoft.Win32; +using System.Drawing.Drawing2D; + +#endregion + +namespace CodeImp.DoomBuilder.Interface +{ + public partial class CheckboxArrayControl : UserControl + { + // Constants + private const int SPACING_Y = 1; + + // Variables + private List checkboxes; + private int columns; + + // Properties + public List Checkboxes { get { return checkboxes; } } + public int Columns { get { return columns; } set { columns = value; } } + + // Constructor + public CheckboxArrayControl() + { + // Initialize + InitializeComponent(); + + // Setup + checkboxes = new List(); + } + + // This adds a checkbox + public CheckBox Add(string text, object tag) + { + // Make new checkbox + CheckBox c = new CheckBox(); + c.AutoSize = true; + //c.FlatStyle = FlatStyle.System; + c.UseVisualStyleBackColor = true; + c.Text = text; + c.Tag = tag; + + // Add to list + this.Controls.Add(c); + checkboxes.Add(c); + + // Return checkbox + return c; + } + + // This positions the checkboxes + public void PositionCheckboxes() + { + int boxheight = 0; + int columnlength; + int columnwidth; + int row = 0; + int col = 0; + + // Checks + if(columns < 1) return; + if(checkboxes.Count < 1) return; + + // Calculate column width + columnwidth = this.ClientSize.Width / columns; + + // Check what the biggest checkbox height is + foreach(CheckBox c in checkboxes) if(c.Height > boxheight) boxheight = c.Height; + + // Check what the preferred column length is + columnlength = 1 + (int)Math.Floor((float)(this.ClientSize.Height - boxheight) / (float)(boxheight + SPACING_Y)); + + // When not all items fit with the preferred column length + // we have to extend the column length to make it fit + if((int)Math.Ceiling((float)checkboxes.Count / (float)columnlength) > columns) + { + // Make a column length which works for all items + columnlength = (int)Math.Ceiling((float)checkboxes.Count / (float)columns); + } + + // Go for all items + foreach(CheckBox c in checkboxes) + { + // Position checkbox + c.Location = new Point(col * columnwidth, row * boxheight + (row - 1) * SPACING_Y + SPACING_Y); + + // Next position + if(++row == columnlength) + { + row = 0; + col++; + } + } + } + + // When layout must change + private void CheckboxArrayControl_Layout(object sender, LayoutEventArgs e) + { + PositionCheckboxes(); + } + + private void CheckboxArrayControl_Paint(object sender, PaintEventArgs e) + { + if(this.DesignMode) + { + Pen p = new Pen(SystemColors.ControlDark, 1); + p.DashStyle = DashStyle.Dash; + e.Graphics.DrawRectangle(p, 0, 0, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1); + } + } + } +} diff --git a/Source/Interface/CheckboxArrayControl.resx b/Source/Interface/CheckboxArrayControl.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/Source/Interface/CheckboxArrayControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Source/Interface/LinedefEditForm.Designer.cs b/Source/Interface/LinedefEditForm.Designer.cs new file mode 100644 index 00000000..811b5669 --- /dev/null +++ b/Source/Interface/LinedefEditForm.Designer.cs @@ -0,0 +1,161 @@ +namespace CodeImp.DoomBuilder.Interface +{ + partial class LinedefEditForm + { + /// + /// 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.cancel = new System.Windows.Forms.Button(); + this.apply = new System.Windows.Forms.Button(); + this.actiongroup = new System.Windows.Forms.GroupBox(); + this.action = new CodeImp.DoomBuilder.Interface.ActionSelectorControl(); + this.browseaction = new System.Windows.Forms.Button(); + this.settingsgroup = new System.Windows.Forms.GroupBox(); + this.flags = new CodeImp.DoomBuilder.Interface.CheckboxArrayControl(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.actiongroup.SuspendLayout(); + this.settingsgroup.SuspendLayout(); + this.SuspendLayout(); + // + // cancel + // + this.cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancel.Location = new System.Drawing.Point(399, 387); + this.cancel.Name = "cancel"; + this.cancel.Size = new System.Drawing.Size(112, 25); + this.cancel.TabIndex = 17; + this.cancel.Text = "Cancel"; + this.cancel.UseVisualStyleBackColor = true; + // + // apply + // + this.apply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.apply.Location = new System.Drawing.Point(281, 387); + this.apply.Name = "apply"; + this.apply.Size = new System.Drawing.Size(112, 25); + this.apply.TabIndex = 16; + this.apply.Text = "OK"; + this.apply.UseVisualStyleBackColor = true; + // + // actiongroup + // + this.actiongroup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.actiongroup.Controls.Add(this.action); + this.actiongroup.Controls.Add(this.browseaction); + this.actiongroup.Location = new System.Drawing.Point(12, 177); + this.actiongroup.Name = "actiongroup"; + this.actiongroup.Size = new System.Drawing.Size(499, 196); + this.actiongroup.TabIndex = 18; + this.actiongroup.TabStop = false; + this.actiongroup.Text = " Action "; + // + // action + // + this.action.BackColor = System.Drawing.SystemColors.Control; + this.action.Cursor = System.Windows.Forms.Cursors.Default; + this.action.Location = new System.Drawing.Point(18, 27); + this.action.Name = "action"; + this.action.Size = new System.Drawing.Size(430, 21); + this.action.TabIndex = 5; + // + // browseaction + // + this.browseaction.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.browseaction.Image = global::CodeImp.DoomBuilder.Properties.Resources.treeview; + this.browseaction.Location = new System.Drawing.Point(454, 26); + this.browseaction.Name = "browseaction"; + this.browseaction.Padding = new System.Windows.Forms.Padding(0, 0, 1, 3); + this.browseaction.Size = new System.Drawing.Size(30, 23); + this.browseaction.TabIndex = 3; + this.browseaction.Text = " "; + this.browseaction.UseVisualStyleBackColor = true; + // + // settingsgroup + // + this.settingsgroup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.settingsgroup.Controls.Add(this.flags); + this.settingsgroup.Location = new System.Drawing.Point(12, 12); + this.settingsgroup.Name = "settingsgroup"; + this.settingsgroup.Size = new System.Drawing.Size(499, 152); + this.settingsgroup.TabIndex = 19; + this.settingsgroup.TabStop = false; + this.settingsgroup.Text = " Settings "; + // + // flags + // + this.flags.AutoScroll = true; + this.flags.Columns = 3; + this.flags.Location = new System.Drawing.Point(18, 26); + this.flags.Name = "flags"; + this.flags.Size = new System.Drawing.Size(475, 119); + this.flags.TabIndex = 0; + // + // checkBox1 + // + this.checkBox1.Location = new System.Drawing.Point(0, 0); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(104, 24); + this.checkBox1.TabIndex = 0; + this.checkBox1.Text = "checkBox1"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // LinedefEditForm + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.ClientSize = new System.Drawing.Size(523, 422); + this.Controls.Add(this.settingsgroup); + this.Controls.Add(this.actiongroup); + this.Controls.Add(this.cancel); + this.Controls.Add(this.apply); + this.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "LinedefEditForm"; + this.Opacity = 0; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Edit Linedefs"; + this.actiongroup.ResumeLayout(false); + this.settingsgroup.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button cancel; + private System.Windows.Forms.Button apply; + private System.Windows.Forms.GroupBox actiongroup; + private System.Windows.Forms.GroupBox settingsgroup; + private CheckboxArrayControl flags; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.Button browseaction; + private ActionSelectorControl action; + } +} \ No newline at end of file diff --git a/Source/Interface/LinedefEditForm.cs b/Source/Interface/LinedefEditForm.cs new file mode 100644 index 00000000..64037519 --- /dev/null +++ b/Source/Interface/LinedefEditForm.cs @@ -0,0 +1,86 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * 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. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using CodeImp.DoomBuilder.Map; +using CodeImp.DoomBuilder.Data; +using CodeImp.DoomBuilder.IO; +using System.IO; +using CodeImp.DoomBuilder.Config; + +#endregion + +namespace CodeImp.DoomBuilder.Interface +{ + public partial class LinedefEditForm : DelayedForm + { + // Variables + private ICollection lines; + + // Constructor + public LinedefEditForm() + { + // Initialize + InitializeComponent(); + + // Fill linedef flags list + foreach(KeyValuePair lf in General.Map.Config.LinedefFlags) flags.Add(lf.Value, lf.Key); + + // Fill linedef actions list + action.AddInfo(General.Map.Config.SortedLinedefActions.ToArray()); + } + + // This sets up the form to edit the given lines + public void Setup(ICollection lines) + { + // Keep this list + this.lines = lines; + + // Go for all flags + foreach(CheckBox c in flags.Checkboxes) + { + // Set the option with the first line's setting + c.Checked = (General.GetByIndex(lines, 0).Flags & (int)c.Tag) != 0; + + // Go for all lines + foreach(Linedef l in lines) + { + // Make the option gray if it is different + if(((l.Flags & (int)c.Tag) != 0) != c.Checked) + c.CheckState = CheckState.Indeterminate; + } + } + + // Set the action to the first line's action + action.Value = General.GetByIndex(lines, 0).Action; + + // Go for all lines + foreach(Linedef l in lines) + { + // Erase the option if it is different + if(l.Action != action.Value) + action.Empty = true; + } + } + } +} diff --git a/Source/Interface/LinedefEditForm.resx b/Source/Interface/LinedefEditForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/Source/Interface/LinedefEditForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Source/Interface/ResourceOptionsForm.Designer.cs b/Source/Interface/ResourceOptionsForm.Designer.cs index 95309e42..766ece24 100644 --- a/Source/Interface/ResourceOptionsForm.Designer.cs +++ b/Source/Interface/ResourceOptionsForm.Designer.cs @@ -40,13 +40,13 @@ namespace CodeImp.DoomBuilder.Interface this.dir_textures = new System.Windows.Forms.CheckBox(); this.browsedir = new System.Windows.Forms.Button(); this.dirlocation = new System.Windows.Forms.TextBox(); + this.pk3filetab = new System.Windows.Forms.TabPage(); + this.browsepk3 = new System.Windows.Forms.Button(); + this.pk3location = new System.Windows.Forms.TextBox(); this.cancel = new System.Windows.Forms.Button(); this.apply = new System.Windows.Forms.Button(); this.wadfiledialog = new System.Windows.Forms.OpenFileDialog(); this.dirdialog = new System.Windows.Forms.FolderBrowserDialog(); - this.pk3filetab = new System.Windows.Forms.TabPage(); - this.browsepk3 = new System.Windows.Forms.Button(); - this.pk3location = new System.Windows.Forms.TextBox(); this.pk3filedialog = new System.Windows.Forms.OpenFileDialog(); label1 = new System.Windows.Forms.Label(); label2 = new System.Windows.Forms.Label(); @@ -75,6 +75,15 @@ namespace CodeImp.DoomBuilder.Interface label2.TabIndex = 3; label2.Text = "Directory Resource:"; // + // label3 + // + label3.AutoSize = true; + label3.Location = new System.Drawing.Point(15, 20); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(98, 14); + label3.TabIndex = 3; + label3.Text = "PK3 File Resource:"; + // // tabs // this.tabs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) @@ -108,11 +117,13 @@ namespace CodeImp.DoomBuilder.Interface // browsewad // this.browsewad.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.browsewad.Image = global::CodeImp.DoomBuilder.Properties.Resources.Folder; this.browsewad.Location = new System.Drawing.Point(315, 36); this.browsewad.Name = "browsewad"; + this.browsewad.Padding = new System.Windows.Forms.Padding(0, 0, 1, 3); this.browsewad.Size = new System.Drawing.Size(30, 23); this.browsewad.TabIndex = 2; - this.browsewad.Text = "..."; + this.browsewad.Text = " "; this.browsewad.UseVisualStyleBackColor = true; this.browsewad.Click += new System.EventHandler(this.browsewad_Click); // @@ -163,11 +174,12 @@ namespace CodeImp.DoomBuilder.Interface // browsedir // this.browsedir.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.browsedir.Image = global::CodeImp.DoomBuilder.Properties.Resources.Folder; this.browsedir.Location = new System.Drawing.Point(316, 91); this.browsedir.Name = "browsedir"; + this.browsedir.Padding = new System.Windows.Forms.Padding(0, 0, 1, 3); this.browsedir.Size = new System.Drawing.Size(30, 23); this.browsedir.TabIndex = 5; - this.browsedir.Text = "..."; this.browsedir.UseVisualStyleBackColor = true; this.browsedir.Click += new System.EventHandler(this.browsedir_Click); // @@ -180,6 +192,39 @@ namespace CodeImp.DoomBuilder.Interface this.dirlocation.Size = new System.Drawing.Size(293, 20); this.dirlocation.TabIndex = 4; // + // pk3filetab + // + this.pk3filetab.Controls.Add(this.browsepk3); + this.pk3filetab.Controls.Add(this.pk3location); + this.pk3filetab.Controls.Add(label3); + this.pk3filetab.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.pk3filetab.Location = new System.Drawing.Point(4, 23); + this.pk3filetab.Name = "pk3filetab"; + this.pk3filetab.Size = new System.Drawing.Size(361, 134); + this.pk3filetab.TabIndex = 2; + this.pk3filetab.Text = "From PK3 File"; + this.pk3filetab.UseVisualStyleBackColor = true; + // + // browsepk3 + // + this.browsepk3.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.browsepk3.Image = global::CodeImp.DoomBuilder.Properties.Resources.Folder; + this.browsepk3.Location = new System.Drawing.Point(315, 36); + this.browsepk3.Name = "browsepk3"; + this.browsepk3.Padding = new System.Windows.Forms.Padding(0, 0, 1, 3); + this.browsepk3.Size = new System.Drawing.Size(30, 23); + this.browsepk3.TabIndex = 5; + this.browsepk3.UseVisualStyleBackColor = true; + this.browsepk3.Click += new System.EventHandler(this.browsepk3_Click); + // + // pk3location + // + this.pk3location.Location = new System.Drawing.Point(17, 37); + this.pk3location.Name = "pk3location"; + this.pk3location.ReadOnly = true; + this.pk3location.Size = new System.Drawing.Size(292, 20); + this.pk3location.TabIndex = 4; + // // cancel // this.cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); @@ -212,47 +257,6 @@ namespace CodeImp.DoomBuilder.Interface // this.dirdialog.Description = "Please select a directory from which to load images when editing your map..."; // - // pk3filetab - // - this.pk3filetab.Controls.Add(this.browsepk3); - this.pk3filetab.Controls.Add(this.pk3location); - this.pk3filetab.Controls.Add(label3); - this.pk3filetab.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.pk3filetab.Location = new System.Drawing.Point(4, 23); - this.pk3filetab.Name = "pk3filetab"; - this.pk3filetab.Size = new System.Drawing.Size(361, 134); - this.pk3filetab.TabIndex = 2; - this.pk3filetab.Text = "From PK3 File"; - this.pk3filetab.UseVisualStyleBackColor = true; - // - // browsepk3 - // - this.browsepk3.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.browsepk3.Location = new System.Drawing.Point(315, 36); - this.browsepk3.Name = "browsepk3"; - this.browsepk3.Size = new System.Drawing.Size(30, 23); - this.browsepk3.TabIndex = 5; - this.browsepk3.Text = "..."; - this.browsepk3.UseVisualStyleBackColor = true; - this.browsepk3.Click += new System.EventHandler(this.browsepk3_Click); - // - // pk3location - // - this.pk3location.Location = new System.Drawing.Point(17, 37); - this.pk3location.Name = "pk3location"; - this.pk3location.ReadOnly = true; - this.pk3location.Size = new System.Drawing.Size(292, 20); - this.pk3location.TabIndex = 4; - // - // label3 - // - label3.AutoSize = true; - label3.Location = new System.Drawing.Point(15, 20); - label3.Name = "label3"; - label3.Size = new System.Drawing.Size(98, 14); - label3.TabIndex = 3; - label3.Text = "PK3 File Resource:"; - // // pk3filedialog // this.pk3filedialog.Filter = "Doom PK3 Files (*.pk3)|*.pk3"; diff --git a/Source/Interface/ResourceOptionsForm.resx b/Source/Interface/ResourceOptionsForm.resx index 7ff6eb5e..f4f8f92f 100644 --- a/Source/Interface/ResourceOptionsForm.resx +++ b/Source/Interface/ResourceOptionsForm.resx @@ -129,6 +129,12 @@ False + + True + + + False + True @@ -165,30 +171,6 @@ True - - True - - - False - - - True - - - True - - - True - - - True - - - True - - - True - True diff --git a/Source/Map/Linedef.cs b/Source/Map/Linedef.cs index 9fe26974..4f281992 100644 --- a/Source/Map/Linedef.cs +++ b/Source/Map/Linedef.cs @@ -34,10 +34,8 @@ namespace CodeImp.DoomBuilder.Map { #region ================== Constants - public const int BUFFERVERTICES = 4; - public const int RENDERPRIMITIVES = 2; - public static readonly byte[] EMPTY_ARGS = new byte[5]; - private const float NORMAL_LENGTH = 6f; + public const int NUM_ARGS = 5; + public static readonly byte[] EMPTY_ARGS = new byte[NUM_ARGS]; #endregion @@ -268,10 +266,28 @@ namespace CodeImp.DoomBuilder.Map { updateneeded = true; } - + #endregion #region ================== Methods + + // This applies single/double sided flags + public void ApplySidedFlags() + { + // Doublesided? + if((front != null) && (back != null)) + { + // Apply or remove flags for doublesided line + flags &= ~General.Map.Config.SingleSidedFlags; + flags |= General.Map.Config.DoubleSidedFlags; + } + else + { + // Apply or remove flags for singlesided line + flags &= ~General.Map.Config.DoubleSidedFlags; + flags |= General.Map.Config.SingleSidedFlags; + } + } // This returns the shortest distance from given coordinates to line public float SafeDistanceToSq(Vector2D p, bool bounded) @@ -374,11 +390,158 @@ namespace CodeImp.DoomBuilder.Map // This line will be disposed public void Join(Linedef other) { - // TODO + Sector l1fs, l1bs, l2fs, l2bs; + + // Get sector references + if(other.front != null) l1fs = other.front.Sector; else l1fs = null; + if(other.back != null) l1bs = other.back.Sector; else l1bs = null; + if(this.front != null) l2fs = this.front.Sector; else l2fs = null; + if(this.back != null) l2bs = this.back.Sector; else l2bs = null; + // Compare front sectors + if(l1fs == l2fs) + { + // Copy textures + if(other.front != null) other.front.AddTexturesTo(this.back); + if(this.front != null) this.front.AddTexturesTo(other.back); + + // Change sidedefs + JoinChangeSidedefs(other, true, back); + } + // Compare back sectors + else if(l1bs == l2bs) + { + // Copy textures + if(other.back != null) other.back.AddTexturesTo(this.front); + if(this.back != null) this.back.AddTexturesTo(other.front); + + // Change sidedefs + JoinChangeSidedefs(other, false, front); + } + // Compare front and back + else if(l1fs == l2bs) + { + // Copy textures + if(other.front != null) other.front.AddTexturesTo(this.front); + if(this.back != null) this.back.AddTexturesTo(other.back); + + // Change sidedefs + JoinChangeSidedefs(other, true, front); + } + // Compare back and front + else if(l1bs == l2fs) + { + // Copy textures + if(other.back != null) other.back.AddTexturesTo(this.back); + if(this.front != null) this.front.AddTexturesTo(other.front); + + // Change sidedefs + JoinChangeSidedefs(other, false, back); + } + else + { + // Other line single sided? + if(other.back == null) + { + // This line with its back to the other? + if(this.start == other.end) + { + // Copy textures + if(other.back != null) other.back.AddTexturesTo(this.front); + if(this.back != null) this.back.AddTexturesTo(other.front); + + // Change sidedefs + JoinChangeSidedefs(other, false, front); + } + else + { + // Copy textures + if(other.back != null) other.back.AddTexturesTo(this.back); + if(this.front != null) this.front.AddTexturesTo(other.front); + + // Change sidedefs + JoinChangeSidedefs(other, false, back); + } + } + // This line single sided? + if(this.back == null) + { + // Other line with its back to this? + if(other.start == this.end) + { + // Copy textures + if(other.back != null) other.back.AddTexturesTo(this.front); + if(this.back != null) this.back.AddTexturesTo(other.front); + + // Change sidedefs + JoinChangeSidedefs(other, false, front); + } + else + { + // Copy textures + if(other.front != null) other.front.AddTexturesTo(this.front); + if(this.back != null) this.back.AddTexturesTo(other.back); + + // Change sidedefs + JoinChangeSidedefs(other, true, front); + } + } + else + { + // This line with its back to the other? + if(this.start == other.end) + { + // Copy textures + if(other.back != null) other.back.AddTexturesTo(this.front); + if(this.back != null) this.back.AddTexturesTo(other.front); + + // Change sidedefs + JoinChangeSidedefs(other, false, front); + } + else + { + // Copy textures + if(other.back != null) other.back.AddTexturesTo(this.back); + if(this.front != null) this.front.AddTexturesTo(other.front); + + // Change sidedefs + JoinChangeSidedefs(other, false, back); + } + } + } + + // If either of the two lines was selected, keep the other selected + if(this.selected) other.selected = true; + + // Apply single/double sided flags + other.ApplySidedFlags(); + + // I got killed by the other. this.Dispose(); } + // This changes sidedefs (used for joining lines) + private void JoinChangeSidedefs(Linedef other, bool front, Sidedef newside) + { + Sidedef sd; + + // Change sidedefs + if(front) + { + if(other.front != null) other.front.Dispose(); + } + else + { + if(other.back != null) other.back.Dispose(); + } + + if(newside != null) + { + sd = map.CreateSidedef(other, front, newside.Sector); + newside.CopyPropertiesTo(sd); + } + } + #endregion #region ================== Changes diff --git a/Source/Map/MapSet.cs b/Source/Map/MapSet.cs index cf7a4261..8860165f 100644 --- a/Source/Map/MapSet.cs +++ b/Source/Map/MapSet.cs @@ -26,6 +26,7 @@ using SlimDX.Direct3D; using CodeImp.DoomBuilder.Rendering; using SlimDX; using System.Drawing; +using CodeImp.DoomBuilder.Editing; #endregion @@ -360,6 +361,43 @@ namespace CodeImp.DoomBuilder.Map return list; } + // Returns a collection of vertices that match a selected state on the linedefs + public ICollection GetVerticesFromLinesSelection(bool selected) + { + List list = new List(); + foreach(Vertex v in vertices) + { + foreach(Linedef l in v.Linedefs) + { + if(l.Selected == selected) + { + list.Add(v); + break; + } + } + } + return list; + } + + // Returns a collection of vertices that match a selected state on the linedefs + public ICollection GetVerticesFromSectorsSelection(bool selected) + { + List list = new List(); + foreach(Vertex v in vertices) + { + foreach(Linedef l in v.Linedefs) + { + if( ((l.Front != null) && (l.Front.Sector.Selected == selected)) || + ((l.Back != null) && (l.Back.Sector.Selected == selected)) ) + { + list.Add(v); + break; + } + } + } + return list; + } + // Returns a collection of things that match a selected state public ICollection GetThingsSelection(bool selected) { @@ -389,7 +427,7 @@ namespace CodeImp.DoomBuilder.Map #region ================== Areas // This creates an area from vertices - public static Rectangle AreaFromVertices(ICollection verts) + public static Rectangle CreateArea(ICollection verts) { int l = int.MaxValue; int t = int.MaxValue; @@ -410,15 +448,15 @@ namespace CodeImp.DoomBuilder.Map return new Rectangle(l, t, r - l, b - t); } - // This creates an area from vertices - public static Rectangle AreaFromLines(ICollection lines) + // This creates an area from linedefs + public static Rectangle CreateArea(ICollection lines) { int l = int.MaxValue; int t = int.MaxValue; int r = int.MinValue; int b = int.MinValue; - // Go for all vertices + // Go for all linedefs foreach(Linedef ld in lines) { // Adjust boundaries by vertices @@ -437,7 +475,7 @@ namespace CodeImp.DoomBuilder.Map } // This filters lines by a square area - public static ICollection FilterArea(ICollection lines, ref Rectangle area) + public static ICollection FilterByArea(ICollection lines, ref Rectangle area) { ICollection newlines = new List(lines.Count); @@ -468,7 +506,7 @@ namespace CodeImp.DoomBuilder.Map } // This filters vertices by a square area - public static ICollection FilterArea(ICollection verts, ref Rectangle area) + public static ICollection FilterByArea(ICollection verts, ref Rectangle area) { ICollection newverts = new List(verts.Count); @@ -492,6 +530,63 @@ namespace CodeImp.DoomBuilder.Map #endregion + #region ================== Stitching + + // This stitches geometry + public int StitchGeometry(ICollection movingverts, ICollection fixedverts) + { + ICollection movinglines; + ICollection fixedlines; + ICollection nearbyfixedverts; + Rectangle editarea; + int stitches = 0; + int stitchundo; + + if(General.MainWindow.AutoMerge) + { + // Make undo for the stitching + stitchundo = General.Map.UndoRedo.CreateUndo("stitch geometry", UndoGroup.None, 0, false); + + // Find lines that moved during the drag + movinglines = LinedefsFromSelectedVertices(false, true, true); + + // Find all non-moving lines + fixedlines = LinedefsFromSelectedVertices(true, false, false); + + // Determine area in which we are editing + editarea = MapSet.CreateArea(movinglines); + editarea.Inflate((int)Math.Ceiling(General.Settings.StitchDistance), + (int)Math.Ceiling(General.Settings.StitchDistance)); + + // Join nearby vertices + stitches += MapSet.JoinVertices(fixedverts, movingverts, true, General.Settings.StitchDistance); + + // Update cached values + Update(); + + // Split moving lines with unselected vertices + nearbyfixedverts = MapSet.FilterByArea(fixedverts, ref editarea); + stitches += MapSet.SplitLinesByVertices(movinglines, nearbyfixedverts, General.Settings.StitchDistance, movinglines); + + // Split non-moving lines with selected vertices + fixedlines = MapSet.FilterByArea(fixedlines, ref editarea); + stitches += MapSet.SplitLinesByVertices(fixedlines, movingverts, General.Settings.StitchDistance, movinglines); + + // Remove looped linedefs + stitches += MapSet.RemoveLoopedLinedefs(movinglines); + + // Join overlapping lines + stitches += MapSet.JoinOverlappingLines(movinglines); + + // No stitching done? then withdraw undo + if(stitches == 0) General.Map.UndoRedo.WithdrawUndo(stitchundo); + } + + return stitches; + } + + #endregion + #region ================== Geometry Tools // This joins overlapping lines together @@ -688,7 +783,8 @@ namespace CodeImp.DoomBuilder.Map if(l.DistanceToSq(v.Position, true) <= splitdist2) { // Line is not already referencing v? - if((l.Start != v) && (l.End != v)) + if(((l.Start.X != v.X) || (l.Start.Y != v.Y)) && + ((l.End.X != v.X) || (l.End.Y != v.Y))) { // Split line l with vertex v nl = l.Split(v); diff --git a/Source/Map/Sidedef.cs b/Source/Map/Sidedef.cs index 972ac9b5..9bdeb394 100644 --- a/Source/Map/Sidedef.cs +++ b/Source/Map/Sidedef.cs @@ -154,6 +154,9 @@ namespace CodeImp.DoomBuilder.Map { int copyoffsets = 0; + // s cannot be null + if(s == null) return; + // Upper texture set? if((texnamehigh.Length > 0) && (texnamehigh[0] != '-')) { diff --git a/Source/Map/Thing.cs b/Source/Map/Thing.cs index 564fbfb2..0e2facc3 100644 --- a/Source/Map/Thing.cs +++ b/Source/Map/Thing.cs @@ -34,7 +34,8 @@ namespace CodeImp.DoomBuilder.Map { #region ================== Constants - public static readonly byte[] EMPTY_ARGS = new byte[5]; + public const int NUM_ARGS = 5; + public static readonly byte[] EMPTY_ARGS = new byte[NUM_ARGS]; #endregion diff --git a/Source/Map/Vertex.cs b/Source/Map/Vertex.cs index 2a2c518b..add15612 100644 --- a/Source/Map/Vertex.cs +++ b/Source/Map/Vertex.cs @@ -146,7 +146,7 @@ namespace CodeImp.DoomBuilder.Map #endregion #region ================== Methods - + // This returns the distance from given coordinates public float DistanceToSq(Vector2D p) { diff --git a/Source/Properties/Resources.Designer.cs b/Source/Properties/Resources.Designer.cs index fdb932a7..6ccac559 100644 --- a/Source/Properties/Resources.Designer.cs +++ b/Source/Properties/Resources.Designer.cs @@ -81,6 +81,13 @@ namespace CodeImp.DoomBuilder.Properties { } } + internal static System.Drawing.Bitmap Folder { + get { + object obj = ResourceManager.GetObject("Folder", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + internal static System.Drawing.Bitmap Grid2 { get { object obj = ResourceManager.GetObject("Grid2", resourceCulture); @@ -207,6 +214,13 @@ namespace CodeImp.DoomBuilder.Properties { } } + internal static System.Drawing.Bitmap treeview { + get { + object obj = ResourceManager.GetObject("treeview", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + internal static System.Drawing.Bitmap Undo { get { object obj = ResourceManager.GetObject("Undo", resourceCulture); diff --git a/Source/Properties/Resources.resx b/Source/Properties/Resources.resx index bc03f1bc..e1ff729c 100644 --- a/Source/Properties/Resources.resx +++ b/Source/Properties/Resources.resx @@ -118,6 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Folder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Redo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -148,9 +151,6 @@ ..\Resources\mergegeometry.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\NewMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Undo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -166,6 +166,9 @@ ..\Resources\Grid2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\OpenMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Grid4.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -187,10 +190,13 @@ ..\Resources\Hourglass.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\OpenMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\mergegeometry2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\NewMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\treeview.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Source/Resources/Folder.png b/Source/Resources/Folder.png new file mode 100644 index 00000000..1d415fd6 Binary files /dev/null and b/Source/Resources/Folder.png differ diff --git a/Source/Resources/treeview.png b/Source/Resources/treeview.png new file mode 100644 index 00000000..0bbd274f Binary files /dev/null and b/Source/Resources/treeview.png differ