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