From 447851e457bdd748a19242c44f5bd099a84c268a Mon Sep 17 00:00:00 2001
From: MaxED <j.maxed@gmail.com>
Date: Thu, 22 Dec 2016 15:04:40 +0000
Subject: [PATCH] Added, Textures Browser: redesigned textures list. Textures
 preview size can now be changed from the Textures Browser window. Folders are
 now shown in the textures list. Fixed, Script Editor: Find and Replace window
 now sets keyboard focus to the input textbox when opening the
 window/switching between tabs. Fixed, Nodes Viewer mode: SEGS overflows were
 not handled, causing a crash. Also extended SEGS limit is now used. Updated
 ZDoom_DECORATE.cfg (A_SetSize).

---
 Build/Scripting/ZDoom_DECORATE.cfg            |   1 +
 Help/gc_decoratekeys.html                     |   1 -
 Source/Core/Builder.csproj                    |   9 +
 Source/Core/Config/IFilledTextureSet.cs       |   1 -
 Source/Core/Config/ProgramConfiguration.cs    |  14 -
 Source/Core/Config/TextureSet.cs              |   2 -
 Source/Core/Controls/FlatSelectorControl.cs   |  12 +-
 .../Core/Controls/ImageBrowserCategoryItem.cs |  50 ++
 .../Controls/ImageBrowserControl.Designer.cs  | 236 ++++---
 Source/Core/Controls/ImageBrowserControl.cs   | 634 +++++++----------
 Source/Core/Controls/ImageBrowserControl.resx |   3 -
 Source/Core/Controls/ImageBrowserItem.cs      | 249 +++----
 .../Controls/ImageSelectorControl.Designer.cs |   4 +-
 Source/Core/Controls/ImageSelectorControl.cs  |  40 +-
 Source/Core/Controls/ImageSelectorPanel.cs    | 645 ++++++++++++++++++
 Source/Core/Controls/LinedefInfoPanel.cs      |   2 +-
 Source/Core/Controls/SectorInfoPanel.cs       |   5 +-
 .../Core/Controls/TextureSelectorControl.cs   |  12 +-
 Source/Core/Controls/TransparentLabel.cs      |  28 +
 Source/Core/Data/DataManager.cs               |  26 +-
 Source/Core/Data/FileImage.cs                 |  11 -
 Source/Core/Data/ImageData.cs                 |  10 +-
 Source/Core/Data/PK3FileImage.cs              |  11 -
 Source/Core/Data/PreviewManager.cs            |  20 +-
 Source/Core/Data/TEXTURESImage.cs             |  11 -
 Source/Core/Properties/Resources.Designer.cs  |  14 +
 Source/Core/Properties/Resources.resx         |   6 +
 Source/Core/Resources/Folder96.png            | Bin 0 -> 9507 bytes
 Source/Core/Resources/Folder96Up.png          | Bin 0 -> 12292 bytes
 .../Core/Windows/LinedefEditForm.Designer.cs  |   6 -
 .../Windows/LinedefEditFormUDMF.Designer.cs   |   6 -
 .../Core/Windows/PreferencesForm.Designer.cs  | 135 +---
 Source/Core/Windows/PreferencesForm.cs        |  13 -
 .../Windows/ScriptFindReplaceForm.Designer.cs |   1 +
 Source/Core/Windows/ScriptFindReplaceForm.cs  |  10 +
 .../Core/Windows/SectorEditForm.Designer.cs   |  26 -
 Source/Core/Windows/SectorEditForm.resx       |   6 -
 .../Windows/SectorEditFormUDMF.Designer.cs    |   2 -
 .../Windows/TextureBrowserForm.Designer.cs    |  10 +-
 Source/Core/Windows/TextureBrowserForm.cs     | 279 +++++---
 .../Core/Windows/TextureSetForm.Designer.cs   |   1 -
 Source/Core/Windows/TextureSetForm.cs         |  10 +-
 .../Interface/JitterSectorsForm.Designer.cs   |   2 -
 .../Interface/MakeDoorForm.Designer.cs        |   4 -
 .../SectorDrawingOptionsPanel.Designer.cs     |   5 -
 Source/Plugins/NodesViewer/NodesViewerMode.cs |  21 +-
 46 files changed, 1623 insertions(+), 971 deletions(-)
 create mode 100644 Source/Core/Controls/ImageBrowserCategoryItem.cs
 create mode 100644 Source/Core/Controls/ImageSelectorPanel.cs
 create mode 100644 Source/Core/Controls/TransparentLabel.cs
 create mode 100644 Source/Core/Resources/Folder96.png
 create mode 100644 Source/Core/Resources/Folder96Up.png

diff --git a/Build/Scripting/ZDoom_DECORATE.cfg b/Build/Scripting/ZDoom_DECORATE.cfg
index 644afae1f..bdc1a7cbe 100644
--- a/Build/Scripting/ZDoom_DECORATE.cfg
+++ b/Build/Scripting/ZDoom_DECORATE.cfg
@@ -252,6 +252,7 @@ keywords
 	A_SetScale = "A_SetScale(float scaleX[, float scaleY = scaleX[, int pointer = AAPTR_DEFAULT[, bool usezero = false]]])";
 	A_SetShadow = "A_SetShadow";
 	A_SetShootable = "A_SetShootable";
+	A_SetSize = "bool A_SetSize(float newradius[, float newheight = -1[, bool testpos = false]])";
 	A_SetSolid = "A_SetSolid";
 	A_SetSpecial = "A_SetSpecial(int special, int arg0, int arg1, int arg2, int arg3, int arg4)";
 	A_SetSpecies = "A_SetSpecies(str species[, int pointer = AAPTR_DEFAULT])";
diff --git a/Help/gc_decoratekeys.html b/Help/gc_decoratekeys.html
index 9d6140253..184b8b344 100644
--- a/Help/gc_decoratekeys.html
+++ b/Help/gc_decoratekeys.html
@@ -65,7 +65,6 @@
    	<li>&quot;<strong>Circle</strong>&quot;. The argument value is used as circle radius.</li>
    </ul> 
    Rendering shapes can be toggled using &quot;<strong><a href="gzdb/features/general/rendering_toolbar.html">Toggle Event Lines</a></strong>&quot; action/menu button.<br />
-   Currently rendering shapes are shown only in Classic modes.<br />
    This property must be used in conjunction with the &quot;<strong>//$ArgN</strong>&quot; property.<br />
   	<br />
   	<strong><a name="argrendercolor" id="argrendercolor"></a>//$ArgNRenderColor &lt;integer&gt;</strong> - <span class="red">GZDB only</span>.<br />
diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index b88a64719..fdc247c60 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -715,12 +715,19 @@
     <Compile Include="Actions\HintsManager.cs" />
     <Compile Include="Config\AllTexturesSet.cs" />
     <Compile Include="Config\FlagTranslation.cs" />
+    <Compile Include="Controls\ImageBrowserCategoryItem.cs" />
+    <Compile Include="Controls\ImageSelectorPanel.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="Controls\Scripting\FindUsagesControl.cs">
       <SubType>UserControl</SubType>
     </Compile>
     <Compile Include="Controls\Scripting\FindUsagesControl.Designer.cs">
       <DependentUpon>FindUsagesControl.cs</DependentUpon>
     </Compile>
+    <Compile Include="Controls\TransparentLabel.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="Data\Scripting\FindUsagesResult.cs" />
     <Compile Include="Controls\Scripting\ScriptIconsManager.cs" />
     <Compile Include="Controls\Scripting\ScriptResourceDocumentTab.cs">
@@ -1206,6 +1213,8 @@
     <None Include="Resources\FixedThingsScale.png" />
     <None Include="Resources\ErrorLargeMapObject.png" />
     <None Include="Resources\ErrorLargeText.png" />
+    <EmbeddedResource Include="Resources\Folder96.png" />
+    <EmbeddedResource Include="Resources\Folder96Up.png" />
     <Content Include="Resources\Light.png" />
     <None Include="Resources\Lightbulb.png" />
     <None Include="Resources\LightDisabled.png" />
diff --git a/Source/Core/Config/IFilledTextureSet.cs b/Source/Core/Config/IFilledTextureSet.cs
index 2c1c63538..bf9453f44 100644
--- a/Source/Core/Config/IFilledTextureSet.cs
+++ b/Source/Core/Config/IFilledTextureSet.cs
@@ -27,7 +27,6 @@ namespace CodeImp.DoomBuilder.Config
 	{
 		// Properties
 		string Name { get; }
-		int Level { get; } //mxd
 		ICollection<ImageData> Textures { get; }
 		ICollection<ImageData> Flats { get; }
 	}
diff --git a/Source/Core/Config/ProgramConfiguration.cs b/Source/Core/Config/ProgramConfiguration.cs
index 8cecfb91f..0493be733 100644
--- a/Source/Core/Config/ProgramConfiguration.cs
+++ b/Source/Core/Config/ProgramConfiguration.cs
@@ -44,7 +44,6 @@ namespace CodeImp.DoomBuilder.Config
 		
 		// Cached variables
 		private bool blackbrowsers;
-		private bool capitalizetexturenames; //mxd
 		private int visualfov;
 		private float visualmousesensx;
 		private float visualmousesensy;
@@ -65,7 +64,6 @@ namespace CodeImp.DoomBuilder.Config
 		private float viewdistance;
 		private bool invertyaxis;
 		private string screenshotspath; //mxd
-		private int previewimagesize;
 		private int autoscrollspeed;
 		private int zoomfactor;
 		private bool showerrorswindow;
@@ -88,7 +86,6 @@ namespace CodeImp.DoomBuilder.Config
 		private int antialiasingsamples; //mxd
 		private bool showtexturesizes;
 		private bool locatetexturegroup; //mxd
-		private bool keeptexturefilterfocused; //mxd
 		private SplitLineBehavior splitlinebehavior; //mxd
 		private MergeGeometryMode mergegeomode; //mxd
 		private bool splitjoinedsectors; //mxd
@@ -156,7 +153,6 @@ namespace CodeImp.DoomBuilder.Config
 
 		internal Configuration Config { get { return cfg; } }
 		public bool BlackBrowsers { get { return blackbrowsers; } internal set { blackbrowsers = value; } }
-		public bool CapitalizeTextureNames { get { return capitalizetexturenames; } internal set { capitalizetexturenames = value; } } //mxd
 		public int VisualFOV { get { return visualfov; } internal set { visualfov = value; } }
 		public int ImageBrightness { get { return imagebrightness; } internal set { imagebrightness = value; } }
 		public float DoubleSidedAlpha { get { return doublesidedalpha; } internal set { doublesidedalpha = value; doublesidedalphabyte = (byte)(doublesidedalpha * 255f); } }
@@ -176,7 +172,6 @@ namespace CodeImp.DoomBuilder.Config
 		public int MoveSpeed { get { return movespeed; } internal set { movespeed = value; } }
 		public float ViewDistance { get { return viewdistance; } internal set { viewdistance = value; } }
 		public bool InvertYAxis { get { return invertyaxis; } internal set { invertyaxis = value; } }
-		public int PreviewImageSize { get { return previewimagesize; } internal set { previewimagesize = value; } }
 		public int AutoScrollSpeed { get { return autoscrollspeed; } internal set { autoscrollspeed = value; } }
 		public int ZoomFactor { get { return zoomfactor; } internal set { zoomfactor = value; } }
 		public bool ShowErrorsWindow { get { return showerrorswindow; } internal set { showerrorswindow = value; } }
@@ -200,7 +195,6 @@ namespace CodeImp.DoomBuilder.Config
 		public int AntiAliasingSamples { get { return antialiasingsamples; } internal set { antialiasingsamples = value; } } //mxd
 		public bool ShowTextureSizes { get { return showtexturesizes; } internal set { showtexturesizes = value; } }
 		public bool LocateTextureGroup { get { return locatetexturegroup; } internal set { locatetexturegroup = value; } } //mxd
-		public bool KeepTextureFilterFocused { get { return keeptexturefilterfocused; } internal set { keeptexturefilterfocused = value; } } //mxd
 		public SplitLineBehavior SplitLineBehavior { get { return splitlinebehavior; } set { splitlinebehavior = value; } } //mxd
 		public MergeGeometryMode MergeGeometryMode { get { return mergegeomode; } internal set { mergegeomode = value; } } //mxd
 		public bool SplitJoinedSectors { get { return splitjoinedsectors; } internal set { splitjoinedsectors = value; } } //mxd
@@ -302,8 +296,6 @@ namespace CodeImp.DoomBuilder.Config
 			{
 				// Read the cache variables
 				blackbrowsers = cfg.ReadSetting("blackbrowsers", false);
-				capitalizetexturenames = cfg.ReadSetting("capitalizetexturenames", true); //mxd
-				//undolevels = cfg.ReadSetting("undolevels", 20);
 				visualfov = cfg.ReadSetting("visualfov", 80);
 				visualmousesensx = cfg.ReadSetting("visualmousesensx", 40f);
 				visualmousesensy = cfg.ReadSetting("visualmousesensy", 40f);
@@ -324,7 +316,6 @@ namespace CodeImp.DoomBuilder.Config
 				viewdistance = cfg.ReadSetting("viewdistance", 3000.0f);
 				invertyaxis = cfg.ReadSetting("invertyaxis", false);
 				screenshotspath = cfg.ReadSetting("screenshotspath", General.DefaultScreenshotsPath); //mxd
-				previewimagesize = cfg.ReadSetting("previewimagesize", 1);
 				autoscrollspeed = cfg.ReadSetting("autoscrollspeed", 0);
 				zoomfactor = cfg.ReadSetting("zoomfactor", 3);
 				showerrorswindow = cfg.ReadSetting("showerrorswindow", true);
@@ -347,7 +338,6 @@ namespace CodeImp.DoomBuilder.Config
 				antialiasingsamples = General.Clamp(cfg.ReadSetting("antialiasingsamples", 4), 0, 8) / 2 * 2; //mxd
 				showtexturesizes = cfg.ReadSetting("showtexturesizes", true);
 				locatetexturegroup = cfg.ReadSetting("locatetexturegroup", true); //mxd
-				keeptexturefilterfocused = cfg.ReadSetting("keeptexturefilterfocused", true); //mxd
 				splitlinebehavior = (SplitLineBehavior)General.Clamp(cfg.ReadSetting("splitlinebehavior", 0), 0, Enum.GetValues(typeof(SplitLineBehavior)).Length - 1); //mxd
 				mergegeomode = (MergeGeometryMode)General.Clamp(cfg.ReadSetting("mergegeometrymode", (int)MergeGeometryMode.REPLACE), 0, Enum.GetValues(typeof(MergeGeometryMode)).Length - 1); //mxd
 				splitjoinedsectors = cfg.ReadSetting("splitjoinedsectors", true); //mxd
@@ -419,8 +409,6 @@ namespace CodeImp.DoomBuilder.Config
 			
 			// Write the cache variables
 			cfg.WriteSetting("blackbrowsers", blackbrowsers);
-			cfg.WriteSetting("capitalizetexturenames", capitalizetexturenames); //mxd
-			//cfg.WriteSetting("undolevels", undolevels);
 			cfg.WriteSetting("visualfov", visualfov);
 			cfg.WriteSetting("visualmousesensx", visualmousesensx);
 			cfg.WriteSetting("visualmousesensy", visualmousesensy);
@@ -440,7 +428,6 @@ namespace CodeImp.DoomBuilder.Config
 			cfg.WriteSetting("viewdistance", viewdistance);
 			cfg.WriteSetting("invertyaxis", invertyaxis);
 			cfg.WriteSetting("screenshotspath", screenshotspath); //mxd
-			cfg.WriteSetting("previewimagesize", previewimagesize);
 			cfg.WriteSetting("autoscrollspeed", autoscrollspeed);
 			cfg.WriteSetting("zoomfactor", zoomfactor);
 			cfg.WriteSetting("showerrorswindow", showerrorswindow);
@@ -463,7 +450,6 @@ namespace CodeImp.DoomBuilder.Config
 			cfg.WriteSetting("antialiasingsamples", antialiasingsamples); //mxd
 			cfg.WriteSetting("showtexturesizes", showtexturesizes);
 			cfg.WriteSetting("locatetexturegroup", locatetexturegroup); //mxd
-			cfg.WriteSetting("keeptexturefilterfocused", keeptexturefilterfocused); //mxd
 			cfg.WriteSetting("splitlinebehavior", (int)splitlinebehavior); //mxd
 			cfg.WriteSetting("mergegeometrymode", (int)mergegeomode); //mxd
 			cfg.WriteSetting("splitjoinedsectors", splitjoinedsectors); //mxd
diff --git a/Source/Core/Config/TextureSet.cs b/Source/Core/Config/TextureSet.cs
index e6f527829..1df5a46b4 100644
--- a/Source/Core/Config/TextureSet.cs
+++ b/Source/Core/Config/TextureSet.cs
@@ -28,7 +28,6 @@ namespace CodeImp.DoomBuilder.Config
 		#region ================== Variables
 
 		protected string name;
-		private int level; //mxd. Folder depth of this item
 		protected List<string> filters;
 		
 		#endregion
@@ -36,7 +35,6 @@ namespace CodeImp.DoomBuilder.Config
 		#region ================== Properties
 		
 		public string Name { get { return name; } set { name = value; } }
-		public int Level { get { return level; } set { level = value; } }
 		internal List<string> Filters { get { return filters; } }
 		
 		#endregion
diff --git a/Source/Core/Controls/FlatSelectorControl.cs b/Source/Core/Controls/FlatSelectorControl.cs
index a0d287ce5..bd4fecf32 100644
--- a/Source/Core/Controls/FlatSelectorControl.cs
+++ b/Source/Core/Controls/FlatSelectorControl.cs
@@ -16,6 +16,7 @@
 
 #region ================== Namespaces
 
+using System;
 using System.Drawing;
 using CodeImp.DoomBuilder.Windows;
 using CodeImp.DoomBuilder.Data;
@@ -64,14 +65,19 @@ namespace CodeImp.DoomBuilder.Controls
 
 				if(string.IsNullOrEmpty(texture.FilePathName) || texture is UnknownImage) DisplayImageSize(0, 0); //mxd
 				else DisplayImageSize(texture.ScaledWidth, texture.ScaledHeight); //mxd
-				if(usepreviews ? !texture.IsPreviewLoaded : !texture.IsImageLoaded) timer.Start(); //mxd
+				if(!texture.IsPreviewLoaded) timer.Start(); //mxd
 				
 				// Set the image
-				// mxd. GetPreview() returns a copy of preview, GetBitmap() returns actual bitmap
-				return (usepreviews ? texture.GetPreview() : new Bitmap(texture.GetBitmap()));
+				return texture.GetPreview();
 			}
 		}
 
+		//mxd. This gets ImageData by name...
+		protected override ImageData GetImageData(string imagename)
+		{
+			return General.Map.Data.GetFlatImage(imagename);
+		}
+
 		// This browses for a flat
 		protected override string BrowseImage(string imagename)
 		{
diff --git a/Source/Core/Controls/ImageBrowserCategoryItem.cs b/Source/Core/Controls/ImageBrowserCategoryItem.cs
new file mode 100644
index 000000000..ab8bfa6dc
--- /dev/null
+++ b/Source/Core/Controls/ImageBrowserCategoryItem.cs
@@ -0,0 +1,50 @@
+#region ================== Namespaces
+
+using System;
+using CodeImp.DoomBuilder.Data;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.Controls
+{
+	internal class ImageBrowserCategoryItem : ImageBrowserItem
+	{
+		#region ================== Variables
+
+		private string groupname;
+
+		#endregion
+
+		#region ================== Properties
+
+		public override bool IsPreviewLoaded { get { return true; } }
+		public override string TextureName { get { return groupname; } }
+
+		#endregion
+
+		#region ================== Constructors
+
+		private ImageBrowserCategoryItem(ImageData icon, string tooltip, bool showfullname) : base(icon, tooltip, showfullname) { }
+		public ImageBrowserCategoryItem(ImageBrowserItemType itemtype, string groupname)
+		{
+			this.groupname = groupname;
+			this.itemtype = itemtype;
+			
+			switch(itemtype)
+			{
+				case ImageBrowserItemType.FOLDER:
+					icon = General.Map.Data.FolderTexture;
+					break;
+
+				case ImageBrowserItemType.FOLDER_UP:
+					icon = General.Map.Data.FolderUpTexture;
+					break;
+
+				default:
+					throw new NotImplementedException("Unsupported ItemType");
+			}
+		}
+
+		#endregion
+	}
+}
diff --git a/Source/Core/Controls/ImageBrowserControl.Designer.cs b/Source/Core/Controls/ImageBrowserControl.Designer.cs
index e376addfc..6b2f44070 100644
--- a/Source/Core/Controls/ImageBrowserControl.Designer.cs
+++ b/Source/Core/Controls/ImageBrowserControl.Designer.cs
@@ -33,16 +33,19 @@ namespace CodeImp.DoomBuilder.Controls
 			this.labelMixMode = new System.Windows.Forms.Label();
 			this.label = new System.Windows.Forms.Label();
 			this.splitter = new System.Windows.Forms.SplitContainer();
-			this.list = new CodeImp.DoomBuilder.Controls.OptimizedListView();
-			this.showsubdirtextures = new System.Windows.Forms.CheckBox();
+			this.objectclear = new System.Windows.Forms.Button();
+			this.sizecombo = new System.Windows.Forms.ComboBox();
+			this.label1 = new System.Windows.Forms.Label();
+			this.usedtexturesonly = new System.Windows.Forms.CheckBox();
 			this.longtexturenames = new System.Windows.Forms.CheckBox();
 			this.filterheightlabel = new System.Windows.Forms.Label();
-			this.filterHeight = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
 			this.filterwidthlabel = new System.Windows.Forms.Label();
-			this.filterWidth = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
-			this.cbMixMode = new System.Windows.Forms.ComboBox();
+			this.texturetypecombo = new System.Windows.Forms.ComboBox();
 			this.objectname = new System.Windows.Forms.TextBox();
 			this.refreshtimer = new System.Windows.Forms.Timer(this.components);
+			this.list = new CodeImp.DoomBuilder.Controls.ImageSelectorPanel();
+			this.filterHeight = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
+			this.filterWidth = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
 			this.splitter.Panel1.SuspendLayout();
 			this.splitter.Panel2.SuspendLayout();
 			this.splitter.SuspendLayout();
@@ -51,7 +54,7 @@ namespace CodeImp.DoomBuilder.Controls
 			// labelMixMode
 			// 
 			this.labelMixMode.AutoSize = true;
-			this.labelMixMode.Location = new System.Drawing.Point(3, 9);
+			this.labelMixMode.Location = new System.Drawing.Point(3, 8);
 			this.labelMixMode.Name = "labelMixMode";
 			this.labelMixMode.Size = new System.Drawing.Size(37, 13);
 			this.labelMixMode.TabIndex = 0;
@@ -60,7 +63,7 @@ namespace CodeImp.DoomBuilder.Controls
 			// label
 			// 
 			this.label.AutoSize = true;
-			this.label.Location = new System.Drawing.Point(131, 9);
+			this.label.Location = new System.Drawing.Point(164, 9);
 			this.label.Name = "label";
 			this.label.Size = new System.Drawing.Size(32, 13);
 			this.label.TabIndex = 0;
@@ -81,59 +84,79 @@ namespace CodeImp.DoomBuilder.Controls
 			// 
 			// splitter.Panel2
 			// 
-			this.splitter.Panel2.Controls.Add(this.showsubdirtextures);
+			this.splitter.Panel2.Controls.Add(this.objectclear);
+			this.splitter.Panel2.Controls.Add(this.sizecombo);
+			this.splitter.Panel2.Controls.Add(this.label1);
+			this.splitter.Panel2.Controls.Add(this.usedtexturesonly);
 			this.splitter.Panel2.Controls.Add(this.longtexturenames);
 			this.splitter.Panel2.Controls.Add(this.filterheightlabel);
 			this.splitter.Panel2.Controls.Add(this.filterHeight);
 			this.splitter.Panel2.Controls.Add(this.filterwidthlabel);
 			this.splitter.Panel2.Controls.Add(this.filterWidth);
-			this.splitter.Panel2.Controls.Add(this.cbMixMode);
+			this.splitter.Panel2.Controls.Add(this.texturetypecombo);
 			this.splitter.Panel2.Controls.Add(this.labelMixMode);
 			this.splitter.Panel2.Controls.Add(this.objectname);
 			this.splitter.Panel2.Controls.Add(this.label);
 			this.splitter.Size = new System.Drawing.Size(840, 346);
-			this.splitter.SplitterDistance = 312;
+			this.splitter.SplitterDistance = 284;
 			this.splitter.TabIndex = 0;
 			this.splitter.TabStop = false;
 			// 
-			// list
-			// 
-			this.list.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.list.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-			this.list.HideSelection = false;
-			this.list.Location = new System.Drawing.Point(0, 0);
-			this.list.MultiSelect = false;
-			this.list.Name = "list";
-			this.list.OwnerDraw = true;
-			this.list.ShowItemToolTips = true;
-			this.list.Size = new System.Drawing.Size(840, 312);
-			this.list.TabIndex = 1;
-			this.list.TabStop = false;
-			this.list.TileSize = new System.Drawing.Size(90, 90);
-			this.list.UseCompatibleStateImageBehavior = false;
-			this.list.View = System.Windows.Forms.View.Tile;
-			this.list.DrawItem += new System.Windows.Forms.DrawListViewItemEventHandler(this.list_DrawItem);
-			this.list.DoubleClick += new System.EventHandler(this.list_DoubleClick);
-			this.list.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.list_ItemSelectionChanged);
-			this.list.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.list_KeyPress);
-			this.list.KeyDown += new System.Windows.Forms.KeyEventHandler(this.list_KeyDown);
-			// 
-			// showsubdirtextures
-			// 
-			this.showsubdirtextures.AutoSize = true;
-			this.showsubdirtextures.Location = new System.Drawing.Point(595, 8);
-			this.showsubdirtextures.Name = "showsubdirtextures";
-			this.showsubdirtextures.Size = new System.Drawing.Size(172, 17);
-			this.showsubdirtextures.TabIndex = 0;
-			this.showsubdirtextures.TabStop = false;
-			this.showsubdirtextures.Text = "Show textures in subdirectories";
-			this.showsubdirtextures.UseVisualStyleBackColor = true;
-			this.showsubdirtextures.CheckedChanged += new System.EventHandler(this.showsubdirtextures_CheckedChanged);
+			// objectclear
+			// 
+			this.objectclear.Image = global::CodeImp.DoomBuilder.Properties.Resources.Close;
+			this.objectclear.Location = new System.Drawing.Point(330, 4);
+			this.objectclear.Name = "objectclear";
+			this.objectclear.Size = new System.Drawing.Size(26, 23);
+			this.objectclear.TabIndex = 3;
+			this.objectclear.TabStop = false;
+			this.objectclear.UseVisualStyleBackColor = true;
+			this.objectclear.Click += new System.EventHandler(this.objectclear_Click);
+			// 
+			// sizecombo
+			// 
+			this.sizecombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+			this.sizecombo.FormattingEnabled = true;
+			this.sizecombo.Items.AddRange(new object[] {
+            "1:1",
+            "64",
+            "96",
+            "128",
+            "192",
+            "256"});
+			this.sizecombo.Location = new System.Drawing.Point(43, 32);
+			this.sizecombo.Margin = new System.Windows.Forms.Padding(3, 3, 6, 3);
+			this.sizecombo.Name = "sizecombo";
+			this.sizecombo.Size = new System.Drawing.Size(107, 21);
+			this.sizecombo.TabIndex = 2;
+			this.sizecombo.TabStop = false;
+			this.sizecombo.SelectedIndexChanged += new System.EventHandler(this.sizecombo_SelectedIndexChanged);
+			// 
+			// label1
+			// 
+			this.label1.AutoSize = true;
+			this.label1.Location = new System.Drawing.Point(10, 35);
+			this.label1.Name = "label1";
+			this.label1.Size = new System.Drawing.Size(30, 13);
+			this.label1.TabIndex = 1;
+			this.label1.Text = "Size:";
+			// 
+			// usedtexturesonly
+			// 
+			this.usedtexturesonly.AutoSize = true;
+			this.usedtexturesonly.Location = new System.Drawing.Point(365, 8);
+			this.usedtexturesonly.Name = "usedtexturesonly";
+			this.usedtexturesonly.Size = new System.Drawing.Size(113, 17);
+			this.usedtexturesonly.TabIndex = 0;
+			this.usedtexturesonly.TabStop = false;
+			this.usedtexturesonly.Text = "Used textures only";
+			this.usedtexturesonly.UseVisualStyleBackColor = true;
+			this.usedtexturesonly.CheckedChanged += new System.EventHandler(this.usedtexturesonly_CheckedChanged);
 			// 
 			// longtexturenames
 			// 
 			this.longtexturenames.AutoSize = true;
-			this.longtexturenames.Location = new System.Drawing.Point(470, 8);
+			this.longtexturenames.Location = new System.Drawing.Point(365, 34);
 			this.longtexturenames.Name = "longtexturenames";
 			this.longtexturenames.Size = new System.Drawing.Size(119, 17);
 			this.longtexturenames.TabIndex = 0;
@@ -145,15 +168,77 @@ namespace CodeImp.DoomBuilder.Controls
 			// filterheightlabel
 			// 
 			this.filterheightlabel.AutoSize = true;
-			this.filterheightlabel.Location = new System.Drawing.Point(367, 9);
+			this.filterheightlabel.Location = new System.Drawing.Point(258, 35);
 			this.filterheightlabel.Name = "filterheightlabel";
 			this.filterheightlabel.Size = new System.Drawing.Size(41, 13);
 			this.filterheightlabel.TabIndex = 0;
 			this.filterheightlabel.Text = "Height:";
 			// 
+			// filterwidthlabel
+			// 
+			this.filterwidthlabel.AutoSize = true;
+			this.filterwidthlabel.Location = new System.Drawing.Point(159, 35);
+			this.filterwidthlabel.Name = "filterwidthlabel";
+			this.filterwidthlabel.Size = new System.Drawing.Size(38, 13);
+			this.filterwidthlabel.TabIndex = 0;
+			this.filterwidthlabel.Text = "Width:";
+			// 
+			// texturetypecombo
+			// 
+			this.texturetypecombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+			this.texturetypecombo.FormattingEnabled = true;
+			this.texturetypecombo.Items.AddRange(new object[] {
+            "All",
+            "Textures",
+            "Flats",
+            "By selection type"});
+			this.texturetypecombo.Location = new System.Drawing.Point(43, 5);
+			this.texturetypecombo.Margin = new System.Windows.Forms.Padding(3, 3, 6, 3);
+			this.texturetypecombo.Name = "texturetypecombo";
+			this.texturetypecombo.Size = new System.Drawing.Size(107, 21);
+			this.texturetypecombo.TabIndex = 0;
+			this.texturetypecombo.TabStop = false;
+			this.texturetypecombo.SelectedIndexChanged += new System.EventHandler(this.texturetypecombo_SelectedIndexChanged);
+			// 
+			// objectname
+			// 
+			this.objectname.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
+			this.objectname.HideSelection = false;
+			this.objectname.Location = new System.Drawing.Point(199, 6);
+			this.objectname.Margin = new System.Windows.Forms.Padding(3, 3, 6, 3);
+			this.objectname.Name = "objectname";
+			this.objectname.Size = new System.Drawing.Size(128, 20);
+			this.objectname.TabIndex = 0;
+			this.objectname.TabStop = false;
+			this.objectname.TextChanged += new System.EventHandler(this.objectname_TextChanged);
+			this.objectname.KeyDown += new System.Windows.Forms.KeyEventHandler(this.objectname_KeyDown);
+			// 
+			// refreshtimer
+			// 
+			this.refreshtimer.Interval = 500;
+			this.refreshtimer.Tick += new System.EventHandler(this.refreshtimer_Tick);
+			// 
+			// list
+			// 
+			this.list.AutoScroll = true;
+			this.list.BackColor = System.Drawing.Color.White;
+			this.list.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+			this.list.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.list.HideSelection = false;
+			this.list.ImageSize = 128;
+			this.list.Location = new System.Drawing.Point(0, 0);
+			this.list.MultiSelect = false;
+			this.list.Name = "list";
+			this.list.Size = new System.Drawing.Size(840, 284);
+			this.list.TabIndex = 1;
+			this.list.Title = "Default group";
+			this.list.ItemDoubleClicked += new CodeImp.DoomBuilder.Controls.ImageSelectorPanel.ItemSelectedEventHandler(this.list_ItemDoubleClicked);
+			this.list.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.list_KeyPress);
+			// 
 			// filterHeight
 			// 
 			this.filterHeight.AllowDecimal = false;
+			this.filterHeight.AllowExpressions = false;
 			this.filterHeight.AllowNegative = false;
 			this.filterHeight.AllowRelative = false;
 			this.filterHeight.ButtonStep = 1;
@@ -162,7 +247,7 @@ namespace CodeImp.DoomBuilder.Controls
 			this.filterHeight.ButtonStepSmall = 0.1F;
 			this.filterHeight.ButtonStepsUseModifierKeys = false;
 			this.filterHeight.ButtonStepsWrapAround = false;
-			this.filterHeight.Location = new System.Drawing.Point(410, 4);
+			this.filterHeight.Location = new System.Drawing.Point(301, 30);
 			this.filterHeight.Name = "filterHeight";
 			this.filterHeight.Size = new System.Drawing.Size(54, 24);
 			this.filterHeight.StepValues = null;
@@ -170,18 +255,10 @@ namespace CodeImp.DoomBuilder.Controls
 			this.filterHeight.TabStop = false;
 			this.filterHeight.WhenTextChanged += new System.EventHandler(this.filterSize_WhenTextChanged);
 			// 
-			// filterwidthlabel
-			// 
-			this.filterwidthlabel.AutoSize = true;
-			this.filterwidthlabel.Location = new System.Drawing.Point(268, 9);
-			this.filterwidthlabel.Name = "filterwidthlabel";
-			this.filterwidthlabel.Size = new System.Drawing.Size(38, 13);
-			this.filterwidthlabel.TabIndex = 0;
-			this.filterwidthlabel.Text = "Width:";
-			// 
 			// filterWidth
 			// 
 			this.filterWidth.AllowDecimal = false;
+			this.filterWidth.AllowExpressions = false;
 			this.filterWidth.AllowNegative = false;
 			this.filterWidth.AllowRelative = false;
 			this.filterWidth.ButtonStep = 1;
@@ -190,7 +267,7 @@ namespace CodeImp.DoomBuilder.Controls
 			this.filterWidth.ButtonStepSmall = 0.1F;
 			this.filterWidth.ButtonStepsUseModifierKeys = false;
 			this.filterWidth.ButtonStepsWrapAround = false;
-			this.filterWidth.Location = new System.Drawing.Point(308, 4);
+			this.filterWidth.Location = new System.Drawing.Point(199, 30);
 			this.filterWidth.Name = "filterWidth";
 			this.filterWidth.Size = new System.Drawing.Size(54, 24);
 			this.filterWidth.StepValues = null;
@@ -198,40 +275,6 @@ namespace CodeImp.DoomBuilder.Controls
 			this.filterWidth.TabStop = false;
 			this.filterWidth.WhenTextChanged += new System.EventHandler(this.filterSize_WhenTextChanged);
 			// 
-			// cbMixMode
-			// 
-			this.cbMixMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-			this.cbMixMode.FormattingEnabled = true;
-			this.cbMixMode.Items.AddRange(new object[] {
-            "All",
-            "Textures",
-            "Flats",
-            "By sel. type"});
-			this.cbMixMode.Location = new System.Drawing.Point(43, 5);
-			this.cbMixMode.Margin = new System.Windows.Forms.Padding(3, 3, 6, 3);
-			this.cbMixMode.Name = "cbMixMode";
-			this.cbMixMode.Size = new System.Drawing.Size(80, 21);
-			this.cbMixMode.TabIndex = 0;
-			this.cbMixMode.TabStop = false;
-			this.cbMixMode.SelectedIndexChanged += new System.EventHandler(this.cbMixMode_SelectedIndexChanged);
-			// 
-			// objectname
-			// 
-			this.objectname.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
-			this.objectname.Location = new System.Drawing.Point(166, 6);
-			this.objectname.Margin = new System.Windows.Forms.Padding(3, 3, 6, 3);
-			this.objectname.Name = "objectname";
-			this.objectname.Size = new System.Drawing.Size(94, 20);
-			this.objectname.TabIndex = 0;
-			this.objectname.TabStop = false;
-			this.objectname.TextChanged += new System.EventHandler(this.objectname_TextChanged);
-			this.objectname.KeyDown += new System.Windows.Forms.KeyEventHandler(this.objectname_KeyDown);
-			// 
-			// refreshtimer
-			// 
-			this.refreshtimer.Interval = 500;
-			this.refreshtimer.Tick += new System.EventHandler(this.refreshtimer_Tick);
-			// 
 			// ImageBrowserControl
 			// 
 			this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
@@ -250,18 +293,21 @@ namespace CodeImp.DoomBuilder.Controls
 		#endregion
 
 		private System.Windows.Forms.SplitContainer splitter;
-		private OptimizedListView list;
+		private CodeImp.DoomBuilder.Controls.ImageSelectorPanel list;
 		private System.Windows.Forms.Timer refreshtimer;
 		private System.Windows.Forms.TextBox objectname;
-		private System.Windows.Forms.ComboBox cbMixMode;
+		private System.Windows.Forms.ComboBox texturetypecombo;
 		private System.Windows.Forms.Label label;
 		private System.Windows.Forms.Label labelMixMode;
-		private ButtonsNumericTextbox filterWidth;
+		private CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox filterWidth;
 		private System.Windows.Forms.Label filterheightlabel;
-		private ButtonsNumericTextbox filterHeight;
+		private CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox filterHeight;
 		private System.Windows.Forms.Label filterwidthlabel;
 		private System.Windows.Forms.CheckBox longtexturenames;
-		private System.Windows.Forms.CheckBox showsubdirtextures;
+		private System.Windows.Forms.CheckBox usedtexturesonly;
+		private System.Windows.Forms.ComboBox sizecombo;
+		private System.Windows.Forms.Label label1;
+		private System.Windows.Forms.Button objectclear;
 
 	}
 }
diff --git a/Source/Core/Controls/ImageBrowserControl.cs b/Source/Core/Controls/ImageBrowserControl.cs
index 7a0e4cd92..980437c65 100644
--- a/Source/Core/Controls/ImageBrowserControl.cs
+++ b/Source/Core/Controls/ImageBrowserControl.cs
@@ -19,7 +19,6 @@
 using System;
 using System.Collections.Generic;
 using System.Drawing;
-using System.Globalization;
 using System.Windows.Forms;
 using CodeImp.DoomBuilder.Data;
 using CodeImp.DoomBuilder.Windows;
@@ -32,12 +31,14 @@ namespace CodeImp.DoomBuilder.Controls
 	{
 		#region ================== Constants
 		
+		private static readonly HashSet<char> AllowedSpecialChars = new HashSet<char>("!@#$%^&*()-_=+<>,.?/'\"\\;:[]{}`~".ToCharArray()); //mxd
+
 		#endregion
 		
 		#region ================== Delegates / Events
 
-		public delegate void SelectedItemChangedDelegate();
-		public delegate void SelectedItemDoubleClickDelegate();
+		public delegate void SelectedItemChangedDelegate(ImageBrowserItem item);
+		public delegate void SelectedItemDoubleClickDelegate(ImageBrowserItem item);
 
 		public event SelectedItemChangedDelegate SelectedItemChanged;
 		public event SelectedItemDoubleClickDelegate SelectedItemDoubleClicked;
@@ -50,21 +51,21 @@ namespace CodeImp.DoomBuilder.Controls
 		private bool preventselection;
 		
 		// States
-		private bool updating;
 		private int keepselected;
-		private bool browseFlats; //mxd
-		private static bool uselongtexturenames; //mxd
-		private static bool showtexturesfromsubdirs; //mxd
-		private int currentlevel; //mxd
+		private bool browseflats; //mxd
+		private bool uselongtexturenames; //mxd
+		private bool blockupdate; //mxd
 		
-		// All items
-		private readonly List<ImageBrowserItem> items;
+		//mxd. All items
+		private Dictionary<string, List<ImageBrowserItem>> items; // <group, <items>>
+		private List<string> groups;
+		private string selectedgroup;
 
-		// Items visible in the list
+		// Filtered items
 		private List<ImageBrowserItem> visibleitems;
 
 		//mxd
-		private static int mixMode;
+		private int texturetype;
 		
 		#endregion
 
@@ -72,11 +73,10 @@ namespace CodeImp.DoomBuilder.Controls
 
 		public bool PreventSelection { get { return preventselection; } set { preventselection = value; } }
 		public bool HideInputBox { get { return splitter.Panel2Collapsed; } set { splitter.Panel2Collapsed = value; } }
-		public bool BrowseFlats { get { return browseFlats; } set { browseFlats = value; } } //mxd
-		public static bool ShowTexturesFromSubDirectories { get { return showtexturesfromsubdirs; } internal set { showtexturesfromsubdirs = value; } } //mxd
-		public static bool UseLongTextureNames { get { return uselongtexturenames; } internal set { uselongtexturenames = value; } } //mxd
-		public ListViewItem SelectedItem { get { if(list.SelectedItems.Count > 0) return list.SelectedItems[0]; else return null; } }
-		
+		public List<ImageBrowserItem> SelectedItems { get { return list.SelectedItems; } } //mxd
+		public ImageBrowserItem SelectedItem { get { return (list.SelectedItems.Count > 0 ? list.SelectedItems[0] : null); } }
+		public string SelectedGroup { get { return selectedgroup; } } //mxd
+
 		#endregion
 
 		#region ================== Constructor / Disposer
@@ -86,7 +86,8 @@ namespace CodeImp.DoomBuilder.Controls
 		{
 			// Initialize
 			InitializeComponent();
-			items = new List<ImageBrowserItem>();
+			items = new Dictionary<string, List<ImageBrowserItem>>();
+			groups = new List<string>();
 
 			//mxd
 			StepsList sizes = new StepsList { 4, 8, 16, 32, 48, 64, 96, 128, 196, 256, 512, 1024 };
@@ -98,8 +99,38 @@ namespace CodeImp.DoomBuilder.Controls
 			{
 				splitter.SplitterDistance = splitter.Height - splitter.Panel2.Height - (int)Math.Round(splitter.SplitterWidth * MainForm.DPIScaler.Height);
 			}
+
+			//mxd
+			list.SelectionChanged += list_SelectionChanged;
 		}
-		
+
+		// This applies the application settings
+		public void ApplySettings(string settingpath, bool browseflats)
+		{
+			blockupdate = true;
+
+			//TODO: group handling doesn't couple well with usedtexturesonly checkbox...
+			this.browseflats = browseflats;
+			uselongtexturenames = General.Map.Options.UseLongTextureNames;
+			selectedgroup = General.Settings.ReadSetting(settingpath + ".selectedgroup", string.Empty);
+			
+			if(string.IsNullOrEmpty(selectedgroup) || (groups.Count > 0 && !groups.Contains(selectedgroup)))
+			{
+				selectedgroup = groups[0];
+			}
+
+			texturetype = General.Settings.ReadSetting(settingpath + ".texturetype", 0);
+			usedtexturesonly.Checked = (groups.IndexOf(selectedgroup) == 1);
+			
+			int imagesize = General.Settings.ReadSetting(settingpath + ".imagesize", 128);
+			sizecombo.Text = (imagesize == 0 ? sizecombo.Items[0].ToString() : imagesize.ToString());
+			list.ImageSize = imagesize;
+
+			ApplySettings();
+
+			blockupdate = false;
+		}
+
 		// This applies the application settings
 		public void ApplySettings()
 		{
@@ -113,52 +144,40 @@ namespace CodeImp.DoomBuilder.Controls
 			// Set the size of preview images
 			if(General.Map != null)
 			{
-				int itemwidth = General.Map.Data.Previews.MaxImageWidth + 26;
-				int itemheight = General.Map.Data.Previews.MaxImageHeight + 26;
-				list.TileSize = new Size(itemwidth, itemheight);
-
 				//mxd
 				if(General.Map.Config.MixTexturesFlats) 
 				{
-					cbMixMode.SelectedIndex = mixMode;
+					texturetypecombo.SelectedIndex = texturetype;
 				} 
 				else 
 				{
-					labelMixMode.Visible = false;
-					cbMixMode.Visible = false;
-					
-					int offset = label.Left - labelMixMode.Left;
-					label.Left -= offset;
-					objectname.Left -= offset;
-					filterWidth.Left -= offset;
-					filterwidthlabel.Left -= offset;
-					filterHeight.Left -= offset;
-					filterheightlabel.Left -= offset;
-					showsubdirtextures.Left -= offset;
-					longtexturenames.Left -= offset;
-					
-					mixMode = 0;
+					labelMixMode.Enabled = false;
+					texturetypecombo.Enabled = false;
+					texturetype = 0;
 				}
 
 				//mxd. Use long texture names?
 				longtexturenames.Checked = (uselongtexturenames && General.Map.Config.UseLongTextureNames);
-				longtexturenames.Visible = General.Map.Config.UseLongTextureNames;
-				if(!General.Map.Config.UseLongTextureNames) 
-					showsubdirtextures.Left = longtexturenames.Left; //mxd
+				longtexturenames.Enabled = General.Map.Config.UseLongTextureNames;
 			}
 			else
 			{
-				longtexturenames.Visible = false; //mxd
+				longtexturenames.Enabled = false; //mxd
 				uselongtexturenames = false; //mxd
-				showsubdirtextures.Left = longtexturenames.Left; //mxd
 			}
 
 			//mxd
-			if(!General.Settings.CapitalizeTextureNames)
-				objectname.CharacterCasing = CharacterCasing.Normal;
+			objectname.CharacterCasing = (longtexturenames.Checked ? CharacterCasing.Normal : CharacterCasing.Upper);
+		}
+
+		//mxd. Save settings
+		public virtual void OnClose(string settingpath)
+		{
+			General.Settings.WriteSetting(settingpath + ".selectedgroup", selectedgroup);
+			General.Settings.WriteSetting(settingpath + ".imagesize", list.ImageSize);
+			if(General.Map.Config.UseLongTextureNames) General.Map.Options.UseLongTextureNames = uselongtexturenames;
 
-			//mxd. Show textures in subfolders?
-			showsubdirtextures.Checked = showtexturesfromsubdirs;
+			CleanUp();
 		}
 
 		// This cleans everything up
@@ -172,34 +191,27 @@ namespace CodeImp.DoomBuilder.Controls
 
 		#region ================== Rendering
 
-		// Draw item
-		private void list_DrawItem(object sender, DrawListViewItemEventArgs e)
-		{
-			if(!updating) (e.Item as ImageBrowserItem).Draw(e.Graphics, e.Bounds);
-		}
-
 		// Refresher
 		private void refreshtimer_Tick(object sender, EventArgs e)
 		{
 			bool allpreviewsloaded = true;
+			bool redrawneeded = false; //mxd
 			
 			// Go for all items
 			foreach(ImageBrowserItem i in list.Items)
 			{
 				// Check if there are still previews that are not loaded
 				allpreviewsloaded &= i.IsPreviewLoaded;
-				
-				// Items needs to be redrawn?
-				if(i.CheckRedrawNeeded())
-				{
-					// Refresh item in list
-					//list.RedrawItems(i.Index, i.Index, false);
-					list.Invalidate();
-				}
+
+				//mxd. Item needs to be redrawn?
+				redrawneeded |= i.CheckRedrawNeeded();
 			}
 
 			// If all previews were loaded, stop this timer
 			if(allpreviewsloaded) refreshtimer.Stop();
+
+			// Redraw the list if needed
+			if(redrawneeded) list.Invalidate();
 		}
 
 		#endregion
@@ -223,32 +235,24 @@ namespace CodeImp.DoomBuilder.Controls
 		// Key pressed in textbox
 		private void objectname_KeyDown(object sender, KeyEventArgs e)
 		{
-			// Check what key is pressed
-			switch(e.KeyData)
+			// Let the list handle arrow keys and such
+			if(list.ProcessKeyDown(e))
+			{
+				e.SuppressKeyPress = true;
+			}
+			// Toggle groups
+			else if(e.KeyData == Keys.Tab)
 			{
-				// Cursor keys
-				case Keys.Left: SelectNextItem(SearchDirectionHint.Left); e.SuppressKeyPress = true; break;
-				case Keys.Right: SelectNextItem(SearchDirectionHint.Right); e.SuppressKeyPress = true; break;
-				case Keys.Up: SelectNextItem(SearchDirectionHint.Up); e.SuppressKeyPress = true;  break;
-				case Keys.Down: SelectNextItem(SearchDirectionHint.Down); e.SuppressKeyPress = true; break;
-
-				// Tab
-				case Keys.Tab: GoToNextSameTexture(); e.SuppressKeyPress = true; break;
+				ShowNextGroup();
+				e.SuppressKeyPress = true;
 			}
 		}
 
-		//mxd. Handle keyboard navigation the same way regardless of list being focused...
-		private void list_KeyDown(object sender, KeyEventArgs e)
+		//mxd
+		private void objectclear_Click(object sender, EventArgs e)
 		{
-			// Check what key is pressed
-			switch(e.KeyData)
-			{
-				// Cursor keys
-				case Keys.Left: SelectNextItem(SearchDirectionHint.Left); e.SuppressKeyPress = true; break;
-				case Keys.Right: SelectNextItem(SearchDirectionHint.Right); e.SuppressKeyPress = true; break;
-				case Keys.Up: SelectNextItem(SearchDirectionHint.Up); e.SuppressKeyPress = true; break;
-				case Keys.Down: SelectNextItem(SearchDirectionHint.Down); e.SuppressKeyPress = true; break;
-			}
+			objectname.Clear();
+			list.Focus();
 		}
 
 		//mxd
@@ -260,40 +264,36 @@ namespace CodeImp.DoomBuilder.Controls
 		//mxd
 		protected override bool ProcessTabKey(bool forward)
 		{
-			GoToNextSameTexture();
+			usedtexturesonly.Checked = !usedtexturesonly.Checked;
 			return false;
 		}
 		
 		// Selection changed
-		private void list_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
+		private void list_SelectionChanged(object sender, List<ImageBrowserItem> selection)
 		{
-			if(!e.IsSelected) return; //mxd. Don't want to trigger this twice
-			
 			// Prevent selecting?
 			if(preventselection)
 			{
-				foreach(ListViewItem i in list.SelectedItems) i.Selected = false;
+				if(selection.Count > 0) list.ClearSelection(); //mxd
 			}
 			else
 			{
 				// Raise event
-				if(SelectedItemChanged != null) SelectedItemChanged();
+				if(SelectedItemChanged != null)
+					SelectedItemChanged(list.SelectedItems.Count > 0 ? list.SelectedItems[0] : null);
 			}
 		}
 		
 		// Doublelicking an item
-		private void list_DoubleClick(object sender, EventArgs e)
+		private void list_ItemDoubleClicked(object sender, ImageBrowserItem item)
 		{
 			if(!preventselection && (list.SelectedItems.Count > 0))
-				if(SelectedItemDoubleClicked != null) SelectedItemDoubleClicked();
+				if(SelectedItemDoubleClicked != null) SelectedItemDoubleClicked(item);
 		}
 
-		//mxd. Transfer focus to Filter textbox
+		//mxd. Transfer input to Filter textbox
 		private void list_KeyPress(object sender, KeyPressEventArgs e)
 		{
-			if(!General.Settings.KeepTextureFilterFocused) return;
-
-			objectname.Focus();
 			if(e.KeyChar == '\b') // Any better way to check for Backspace?..
 			{
 				if(!string.IsNullOrEmpty(objectname.Text) && objectname.SelectionStart > 0 && objectname.SelectionLength == 0)
@@ -303,216 +303,111 @@ namespace CodeImp.DoomBuilder.Controls
 					objectname.SelectionStart = s;
 				}
 			}
-			else
+			if(e.KeyChar == 8 && objectname.Text.Length > 0)
 			{
-				objectname.AppendText(e.KeyChar.ToString(CultureInfo.InvariantCulture));
+				if(objectname.SelectionLength > 0)
+				{
+					objectname.Text = objectname.Text.Substring(0, objectname.SelectionStart) +
+										 objectname.Text.Substring(objectname.SelectionStart + objectname.SelectionLength);
+				}
+				else
+				{
+					objectname.Text = objectname.Text.Substring(0, objectname.Text.Length - 1);
+				}
+			}
+			else if((e.KeyChar >= 'a' && e.KeyChar <= 'z') || (e.KeyChar >= '0' && e.KeyChar <= '9') || AllowedSpecialChars.Contains(e.KeyChar))
+			{
+				if(objectname.SelectionLength > 0)
+				{
+					objectname.Text = objectname.Text.Substring(0, objectname.SelectionStart) +
+										 e.KeyChar +
+										 objectname.Text.Substring(objectname.SelectionStart + objectname.SelectionLength);
+				}
+				else
+				{
+					objectname.Text += e.KeyChar;
+				}
 			}
 		}
 
 		//mxd
-		private void cbMixMode_SelectedIndexChanged(object sender, EventArgs e) 
+		private void texturetypecombo_SelectedIndexChanged(object sender, EventArgs e) 
 		{
-			mixMode = cbMixMode.SelectedIndex;
+			texturetype = texturetypecombo.SelectedIndex;
 			RefillList(false);
 		}
 
+		//mxd
+		private void sizecombo_SelectedIndexChanged(object sender, EventArgs e)
+		{
+			if(blockupdate) return;
+			list.ImageSize = (sizecombo.SelectedIndex == 0 ? 0 : Convert.ToInt32(sizecombo.SelectedItem));
+			list.Focus();
+		}
+
 		//mxd
 		private void longtexturenames_CheckedChanged(object sender, EventArgs e)
 		{
+			if(blockupdate) return;
 			uselongtexturenames = longtexturenames.Checked;
+			objectname.CharacterCasing = (uselongtexturenames ? CharacterCasing.Normal : CharacterCasing.Upper);
 			RefillList(false);
 		}
 
 		//mxd
-		private void showsubdirtextures_CheckedChanged(object sender, EventArgs e)
+		private void usedtexturesonly_CheckedChanged(object sender, EventArgs e)
 		{
-			showtexturesfromsubdirs = showsubdirtextures.Checked;
-			RefillList(false);
+			if(blockupdate) return;
+			ShowNextGroup();
 		}
 		
 		#endregion
 
 		#region ================== Methods
 
-		// This selects the next texture with the same name as the selected texture
-		public void GoToNextSameTexture()
-		{
-			if(list.SelectedItems.Count > 0)
-			{
-				list.Focus(); //mxd
-				ListViewItem selected = list.SelectedItems[0];
-
-				//mxd
-				foreach(ImageBrowserItem n in visibleitems) 
-				{
-					if(n == selected) continue;
-					if(n.Text == selected.Text) 
-					{
-						if(list.IsGroupCollapsed(n.Group)) list.SetGroupCollapsed(n.Group, false);
-						n.Selected = true;
-						n.Focused = true;
-						n.EnsureVisible();
-						return;
-					}
-				}
-			}
-		}
-
 		// This selects an item by longname (mxd - changed from name to longname)
-		public void SelectItem(long longname, ListViewGroup preferredgroup)
+		public void SelectItem(long longname, string preferredgroup)
 		{
-			ImageBrowserItem lvi = null; //mxd
-
 			// Not when selecting is prevented
 			if(preventselection) return;
 
-			// Search in preferred group first
-			if(preferredgroup != null)
+			// Assemble group order
+			List<string> searchorder;
+			if(string.IsNullOrEmpty(preferredgroup) || !groups.Contains(preferredgroup))
 			{
-				foreach(ListViewItem item in list.Items)
-				{
-					ImageBrowserItem curitem = item as ImageBrowserItem;
-					if(curitem != null && longname == curitem.Icon.LongName) //mxd
-					{
-						lvi = curitem;
-						if(item.Group == preferredgroup) break;
-					}
-				}
-			}
-			
-			// Select the item
-			if(lvi != null)
-			{
-				// Select this item
-				list.SelectedItems.Clear();
-				lvi.Selected = true;
-				lvi.EnsureVisible();
-			}
-		}
-		
-		// This performs item sleection by keys
-		private void SelectNextItem(SearchDirectionHint dir)
-		{
-			// Not when selecting is prevented
-			if(preventselection) return;
-			
-			// Nothing selected?
-			if(list.SelectedItems.Count == 0)
-			{
-				// Select first
-				SelectFirstItem();
+				searchorder = new List<string>(groups);
 			}
 			else
 			{
-				//mxd
-				int index = list.SelectedItems[0].Index;
-				int targetindex = -1;
-				ListViewGroup startgroup = list.SelectedItems[0].Group;
-				Rectangle startrect = list.SelectedItems[0].GetBounds(ItemBoundsPortion.Entire);
-				
-				switch(dir)
-				{
-					// Check previous items untill groups match...
-					case SearchDirectionHint.Left:
-						if(list.SelectedIndices[0] > 0)
-						{
-							while(--index > -1)
-							{
-								if(list.Items[index].Group == startgroup)
-								{
-									targetindex = index;
-									break;
-								}
-							}
-						}
-						break;
-
-					// Same thing, other direction...
-					case SearchDirectionHint.Right:
-						if(list.SelectedIndices[0] < list.Items.Count - 1)
-						{
-							while(++index < list.Items.Count)
-							{
-								if(list.Items[index].Group == startgroup)
-								{
-									targetindex = index;
-									break;
-								}
-							}
-						}
-						break;
-
-					// Check previous items untill X coordinate match and Y coordinate is less than the start ones...
-					case SearchDirectionHint.Up:
-						while(--index > -1)
-						{
-							ListViewItem item = list.Items[index];
-							if(item != null && item.Group == startgroup)
-							{
-								Rectangle rect = item.GetBounds(ItemBoundsPortion.Entire);
-								if(rect.X == startrect.X && rect.Y < startrect.Y)
-								{
-									targetindex = index;
-									break;
-								}
-							}
-						}
-						break;
-
-					// Same thing, other direction...
-					case SearchDirectionHint.Down:
-						if(list.SelectedIndices[0] < list.Items.Count - 1)
-						{
-							while(++index < list.Items.Count)
-							{
-								ListViewItem item = list.Items[index];
-								if(item != null && item.Group == startgroup)
-								{
-									Rectangle rect = item.GetBounds(ItemBoundsPortion.Entire);
-									if(rect.X == startrect.X && rect.Y > startrect.Y)
-									{
-										targetindex = index;
-										break;
-									}
-								}
-							}
-						}
-						break;
-				}
+				searchorder = new List<string> { preferredgroup };
+				List<string> othergroups = new List<string>(groups);
+				othergroups.Remove(preferredgroup);
+				searchorder.AddRange(othergroups);
+			}
 
-				//mxd. Use the old method for Up/Down keys, becaue it can jump between Groups...
-				if(targetindex == -1 && (dir == SearchDirectionHint.Up || dir == SearchDirectionHint.Down))
+			// Search for item
+			ImageBrowserItem target = null; //mxd
+			string targetgroup = string.Empty;
+			foreach(string group in searchorder)
+			{
+				foreach(ImageBrowserItem item in items[group])
 				{
-					Point spos = new Point(startrect.Location.X + startrect.Width / 2, startrect.Y + startrect.Height / 2);
-
-					// Try finding 5 times in the given direction
-					for(int i = 0; i < 5; i++)
+					if(item.Icon.LongName == longname) //mxd
 					{
-						// Move point in given direction
-						switch(dir)
-						{
-							case SearchDirectionHint.Up: spos.Y -= list.TileSize.Height / 2; break;
-							case SearchDirectionHint.Down: spos.Y += list.TileSize.Height / 2; break;
-						}
-
-						// Test position
-						ListViewItem lvi = list.GetItemAt(spos.X, spos.Y);
-						if(lvi != null)
-						{
-							targetindex = lvi.Index;
-							break;
-						}
+						target = item;
+						targetgroup = group;
+						break;
 					}
 				}
+			}
+			
+			if(target != null)
+			{
+				// Group switching required?
+				SelectGroup(targetgroup);
 
-				//mxd. Found something?..
-				if(targetindex != -1)
-				{
-					// Select item
-					list.SelectedItems.Clear();
-					list.Items[targetindex].Selected = true;
-					list.SelectedItems[0].EnsureVisible();
-				}
+				// Select the item
+				list.SetSelectedItem(target);
 			}
 		}
 		
@@ -523,53 +418,54 @@ namespace CodeImp.DoomBuilder.Controls
 			if(preventselection) return;
 			
 			// Select first
-			if(list.Items.Count > 0)
-			{
-				list.SelectedItems.Clear();
-				ListViewItem lvi = list.GetItemAt(list.TileSize.Width / 2, list.TileSize.Height / 2);
-				if(lvi != null)
-				{
-					lvi.Selected = true;
-					lvi.EnsureVisible();
-				}
-			}
+			if(list.Items.Count > 0) list.SetSelectedItem(list.Items[0]);
 		}
 		
 		// This adds a group
-		public ListViewGroup AddGroup(string name)
+		public void AddGroup(string name)
 		{
-			ListViewGroup grp = new ListViewGroup(name);
-			list.Groups.Add(grp);
-			return grp;
+			if(groups.Contains(name)) return;
+			groups.Add(name);
+			items.Add(name, new List<ImageBrowserItem>());
 		}
 
-		//mxd
-		public bool IsGroupCollapsed(ListViewGroup group)
+		// This selects a group
+		public void SelectGroup(string groupname)
 		{
-			if(!list.Groups.Contains(group)) return false;
-			return list.IsGroupCollapsed(group);
+			if(string.IsNullOrEmpty(groupname) || groupname == selectedgroup || !groups.Contains(groupname)) return;
+			selectedgroup = groupname;
+			list.SetItems(items[groupname]);
+
+			blockupdate = true;
+			usedtexturesonly.Checked = (groups.IndexOf(selectedgroup) == 1);
+			blockupdate = false;
+
+			RefillList(false);
 		}
 
-		//mxd. This enables group collapsability and optionally collapses it
-		public void SetGroupCollapsed(ListViewGroup group, bool collapse)
+		// This toggles between groups
+		private void ShowNextGroup()
 		{
-			if(!list.Groups.Contains(group)) return;
-			list.SetGroupCollapsed(group, collapse);
+			if(groups.Count < 2) return;
+			int nextgroupindex = groups.IndexOf(selectedgroup) + 1;
+			if(nextgroupindex >= items.Count) nextgroupindex = 0;
+			SelectGroup(groups[nextgroupindex]);
 		}
 		
 		// This begins adding items
-		public void BeginAdding(bool keepselectedindex) { BeginAdding(0, keepselectedindex); } //mxd
-		public void BeginAdding(int selectedlevel, bool keepselectedindex)
+		public void BeginAdding(bool keepselectedindex)
 		{
 			if(keepselectedindex && (list.SelectedItems.Count > 0))
-				keepselected = list.SelectedIndices[0];
+				keepselected = list.Items.IndexOf(list.SelectedItems[0]);
 			else
 				keepselected = -1;
-
-			currentlevel = selectedlevel;
 			
 			// Clean list
 			items.Clear();
+
+			// Re-add groups...
+			foreach(string s in groups)
+				items.Add(s, new List<ImageBrowserItem>());
 			
 			// Stop updating
 			refreshtimer.Enabled = false;
@@ -584,49 +480,67 @@ namespace CodeImp.DoomBuilder.Controls
 			// Start updating
 			refreshtimer.Enabled = true;
 		}
-		
-		// This adds an item
-		public void Add(ImageData image, object tag, ListViewGroup group)
+
+		//mxd. This adds a category item
+		public void AddFolder(ImageBrowserItemType itemtype, string group, string categoryname)
 		{
-			ImageBrowserItem i = new ImageBrowserItem(image, tag, uselongtexturenames); //mxd
-			i.ListGroup = group;
-			i.Group = group;
-			i.ToolTipText = image.Name; //mxd
-			items.Add(i);
+			if(string.IsNullOrEmpty(group)) group = ImageSelectorPanel.DEFAULT_GROUP;
+			if(!items.ContainsKey(group))
+			{
+				items.Add(group, new List<ImageBrowserItem>());
+				groups.Add(group);
+			}
+
+			switch(itemtype)
+			{
+				case ImageBrowserItemType.FOLDER: case ImageBrowserItemType.FOLDER_UP:
+					items[group].Add(new ImageBrowserCategoryItem(itemtype, categoryname));
+					break;
+
+				default: throw new Exception("Unsupported ImageBrowserItemType");
+			}
 		}
 		
 		// This adds an item
-		public void Add(ImageData image, object tag, ListViewGroup group, string tooltiptext)
+		public void AddItem(ImageData image, string group, string tooltip)
+		{
+			if(string.IsNullOrEmpty(group)) group = ImageSelectorPanel.DEFAULT_GROUP;
+			if(!items.ContainsKey(group))
+			{
+				items.Add(group, new List<ImageBrowserItem>());
+				groups.Add(group);
+			}
+			items[group].Add(new ImageBrowserItem(image, tooltip, uselongtexturenames));
+		}
+
+		public void AddItem(ImageData image, string group)
 		{
-			ImageBrowserItem i = new ImageBrowserItem(image, tag, uselongtexturenames); //mxd
-			i.ListGroup = group;
-			i.Group = group;
-			i.ToolTipText = tooltiptext;
-			items.Add(i);
+			AddItem(image, group, string.Empty);
 		}
 
 		// This fills the list based on the objectname filter
 		private void RefillList(bool selectfirst)
 		{
+			if(groups.Count == 0) return;
 			visibleitems = new List<ImageBrowserItem>();
 
+			//mxd. Check group name...
+			if(string.IsNullOrEmpty(selectedgroup))
+			{
+				if(groups.Count == 0) throw new Exception("No groups defined...");
+				selectedgroup = groups[0];
+			}
+
 			//mxd. Store info about currently selected item
 			string selectedname = string.Empty;
-			ListViewGroup selecteditemgroup = null;
-			if(!selectfirst && keepselected == -1 && list.SelectedIndices.Count > 0)
+			if(!selectfirst && keepselected == -1 && list.SelectedItems.Count > 0)
 			{
-				selectedname = list.Items[list.SelectedIndices[0]].Text;
-				selecteditemgroup = list.Items[list.SelectedIndices[0]].Group;
+				selectedname = list.SelectedItems[0].Icon.Name;
 			}
-			
-			// Begin updating list
-			updating = true;
-			//list.SuspendLayout();
-			list.BeginUpdate();
-			
+
 			// Clear list first
-			// Group property of items will be set to null, we will restore it later
-			list.Items.Clear();
+			list.Clear();
+			list.Title = selectedgroup;
 
 			//mxd. Filtering by texture size?
 			int w = filterWidth.GetResult(-1);
@@ -634,39 +548,28 @@ namespace CodeImp.DoomBuilder.Controls
 			
 			// Go for all items
 			ImageBrowserItem previtem = null; //mxd
-			for(int i = items.Count - 1; i > -1; i--)
+			for(int i = items[selectedgroup].Count - 1; i > -1; i--)
 			{
 				// Add item if valid
-				items[i].ShowFullName = uselongtexturenames; //mxd
-				if(ValidateItem(items[i], previtem) && ValidateItemSize(items[i], w, h)) 
+				items[selectedgroup][i].ShowFullName = uselongtexturenames; //mxd
+				if(ValidateItem(items[selectedgroup][i], previtem) && ValidateItemSize(items[selectedgroup][i], w, h)) 
 				{
-					items[i].Group = items[i].ListGroup;
-					items[i].Selected = false;
-					visibleitems.Add(items[i]);
-					previtem = items[i];
+					visibleitems.Add(items[selectedgroup][i]);
+					previtem = items[selectedgroup][i];
 				}
 			}
 			
 			// Fill list
 			visibleitems.Sort();
-			ListViewItem[] array = new ListViewItem[visibleitems.Count];
-			for(int i = 0; i < visibleitems.Count; i++) array[i] = visibleitems[i];
-			list.Items.AddRange(array);
-			
-			// Done updating list
-			updating = false;
-			list.EndUpdate();
-			list.Invalidate();
-			//list.ResumeLayout();
+			list.SetItems(visibleitems);
 			
 			// Make selection?
-			if(!preventselection && (list.Items.Count > 0))
+			if(!preventselection && list.Items.Count > 0)
 			{
 				// Select specific item?
 				if(keepselected > -1)
 				{
-					list.Items[keepselected].Selected = true;
-					list.Items[keepselected].EnsureVisible();
+					list.SetSelectedItem(list.Items[keepselected]);
 				}
 				// Select first item?
 				else if(selectfirst)
@@ -674,23 +577,23 @@ namespace CodeImp.DoomBuilder.Controls
 					SelectFirstItem();
 				}
 				//mxd. Try reselecting the same/next closest item
-				else if(selecteditemgroup != null && !string.IsNullOrEmpty(selectedname))
+				else if(!string.IsNullOrEmpty(selectedname))
 				{
-					ListViewItem bestmatch = null;
+					ImageBrowserItem bestmatch = null;
 					int charsmatched = 1;
-					foreach(ListViewItem item in list.Items)
+					foreach(ImageBrowserItem item in list.Items)
 					{
-						if(item.Group == selecteditemgroup && item.Text[0] == selectedname[0])
+						if(item.ItemType == ImageBrowserItemType.IMAGE && item.Icon.Name[0] == selectedname[0])
 						{
-							if(item.Text == selectedname)
+							if(item.Icon.Name == selectedname)
 							{
 								bestmatch = item;
 								break;
 							}
 
-							for(int i = 1; i < Math.Min(item.Text.Length, selectedname.Length); i++)
+							for(int i = 1; i < Math.Min(item.Icon.Name.Length, selectedname.Length); i++)
 							{
-								if(item.Text[i] != selectedname[i])
+								if(item.Icon.Name[i] != selectedname[i])
 								{
 									if(i > charsmatched)
 									{
@@ -703,48 +606,38 @@ namespace CodeImp.DoomBuilder.Controls
 						}
 					}
 
-					// Select the first item from the same group...
-					if(bestmatch == null)
-					{
-						foreach(ListViewItem item in list.Items)
-						{
-							if(item.Group == selecteditemgroup)
-							{
-								bestmatch = item;
-								break;
-							}
-						}
-					}
-
 					// Select found item
 					if(bestmatch != null)
 					{
-						bestmatch.Selected = true;
-						bestmatch.EnsureVisible();
+						list.SetSelectedItem(bestmatch);
+					}
+					else
+					{
+						SelectFirstItem();
 					}
 				}
 			}
 			
 			// Raise event
-			if((SelectedItemChanged != null) && !preventselection) SelectedItemChanged();
+			if((SelectedItemChanged != null) && !preventselection)
+				SelectedItemChanged(list.SelectedItems.Count > 0 ? list.SelectedItems[0] : null);
 		}
 
 		// This validates an item
 		private bool ValidateItem(ImageBrowserItem item, ImageBrowserItem previtem)
 		{
 			//mxd. Don't show duplicate items
-			if(previtem != null && item.TextureName == previtem.TextureName && item.Group == previtem.Group) return false; //mxd
+			if(previtem != null && item.TextureName == previtem.TextureName) return false; //mxd
 			
 			//mxd. mixMode: 0 = All, 1 = Textures, 2 = Flats, 3 = Based on BrowseFlats
 			if(!splitter.Panel2Collapsed) 
 			{
-				if(mixMode == 1 && item.Icon.IsFlat) return false;
-				if(mixMode == 2 && !item.Icon.IsFlat) return false;
-				if(mixMode == 3 && (browseFlats != item.Icon.IsFlat)) return false;
-				if(!showtexturesfromsubdirs && item.Icon.Level > currentlevel) return false;
+				if(texturetype == 1 && item.Icon.IsFlat) return false;
+				if(texturetype == 2 && !item.Icon.IsFlat) return false;
+				if(texturetype == 3 && (browseflats != item.Icon.IsFlat)) return false;
 			}
 
-			return item.Text.ToUpperInvariant().Contains(objectname.Text.ToUpperInvariant());
+			return item.TextureName.ToUpperInvariant().Contains(objectname.Text.ToUpperInvariant());
 		}
 
 		//mxd. This validates an item's texture size
@@ -756,13 +649,10 @@ namespace CodeImp.DoomBuilder.Controls
 			return true;
 		}
 		
-		// This sends the focus to the textbox
-		public void FocusTextbox()
+		//mxd. This sends the focus to the textures list
+		public void FocusList()
 		{
-			if(General.Settings.KeepTextureFilterFocused) //mxd
-				objectname.Focus();
-			else
-				list.Focus();
+			list.Focus();
 		}
 		
 		#endregion
diff --git a/Source/Core/Controls/ImageBrowserControl.resx b/Source/Core/Controls/ImageBrowserControl.resx
index 39dc5d305..cb19257e9 100644
--- a/Source/Core/Controls/ImageBrowserControl.resx
+++ b/Source/Core/Controls/ImageBrowserControl.resx
@@ -120,9 +120,6 @@
   <metadata name="splitter.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>True</value>
   </metadata>
-  <metadata name="list.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>True</value>
-  </metadata>
   <metadata name="refreshtimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>103, 17</value>
   </metadata>
diff --git a/Source/Core/Controls/ImageBrowserItem.cs b/Source/Core/Controls/ImageBrowserItem.cs
index aafec37e2..1142220f1 100644
--- a/Source/Core/Controls/ImageBrowserItem.cs
+++ b/Source/Core/Controls/ImageBrowserItem.cs
@@ -1,190 +1,167 @@
-
-#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
+#region ================== Namespaces
 
 using System;
 using System.Drawing;
-using System.Windows.Forms;
 using CodeImp.DoomBuilder.Data;
-using System.Drawing.Drawing2D;
-using SlimDX;
 
 #endregion
 
 namespace CodeImp.DoomBuilder.Controls
 {
-	internal class ImageBrowserItem : ListViewItem, IComparable<ImageBrowserItem>
+	#region ================== mxd. ImageBrowserItemType
+
+	internal enum ImageBrowserItemType
 	{
-		#region ================== Constants
+		// Values order is used when sorting ImageBrowserItems!
+		FOLDER_UP,
+		FOLDER,
+		IMAGE,
+	}
 
-		internal const int MAX_NAME_LENGTH = 14; //mxd
+	#endregion
 
-		#endregion
-		
+	internal class ImageBrowserItem : IComparable<ImageBrowserItem>
+	{
 		#region ================== Variables
 
-		// Display image and text
-		public readonly ImageData Icon;
-		private string imagesize; //mxd
-		private bool showfullname; //mxd
-		private static readonly StringFormat format = new StringFormat { Alignment = StringAlignment.Center }; //mxd
-		
-		// Group
-		private ListViewGroup listgroup;
-		
-		// Image cache
+		protected ImageData icon;
 		private bool imageloaded;
-		
+		private bool showfullname;
+		protected ImageBrowserItemType itemtype;
+		private string tooltip;
+
 		#endregion
 
 		#region ================== Properties
 
-		public ListViewGroup ListGroup { get { return listgroup; } set { listgroup = value; } }
-		public bool IsPreviewLoaded { get { return imageloaded; } }
-		public bool ShowFullName { set { showfullname = value; UpdateName(); } }
-		public string TextureName { get { return showfullname ? Icon.Name : Icon.ShortName; } }
+		public ImageData Icon { get { return icon; } }
+		public ImageBrowserItemType ItemType { get { return itemtype; } }
+		public virtual bool IsPreviewLoaded { get { return imageloaded; } }
+		public bool ShowFullName { set { showfullname = value; } }
+		public virtual string TextureName { get { return (showfullname ? icon.Name : icon.ShortName); } }
+		public string ToolTip { get { return tooltip; } }
 
 		#endregion
 
-		#region ================== Constructor / Disposer
+		#region ================== Constructor
 
 		// Constructors
-		public ImageBrowserItem(ImageData icon, object tag, bool showfullname)
+		protected ImageBrowserItem() { } //mxd. Needed for inheritance...
+		public ImageBrowserItem(ImageData icon, string tooltip, bool showfullname)
 		{
 			// Initialize
-			this.Icon = icon;
-			this.Tag = tag;
+			this.icon = icon;
+			this.itemtype = ImageBrowserItemType.IMAGE; //mxd
 			this.showfullname = showfullname; //mxd
-			UpdateName(); //mxd
+			this.imageloaded = icon.IsPreviewLoaded; //mxd
+			this.tooltip = tooltip; //mxd
 		}
-		
+
 		#endregion
-		
+
 		#region ================== Methods
-		
-		// This checks if a redraw is needed
-		public bool CheckRedrawNeeded()
+
+		internal bool CheckRedrawNeeded()
 		{
-			UpdateName(); //mxd. Update texture size if needed
-			return (Icon.IsPreviewLoaded != imageloaded);
+			if(icon.IsPreviewLoaded != imageloaded)
+			{
+				imageloaded = icon.IsPreviewLoaded;
+				return true;
+			}
+			return false;
 		}
-		
-		// This draws the images
-		public void Draw(Graphics g, Rectangle bounds)
+
+		internal void Draw(Graphics g, Image bmp, int x, int y, int w, int h, bool selected)
 		{
-			Brush forecolor;
-			Brush backcolor;
-
-			// Remember if the preview is loaded
-			imageloaded = Icon.IsPreviewLoaded;
-
-			// Drawing settings
-			g.CompositingQuality = CompositingQuality.HighSpeed;
-			g.InterpolationMode = InterpolationMode.NearestNeighbor;
-			g.SmoothingMode = SmoothingMode.HighSpeed;
-			g.PixelOffsetMode = PixelOffsetMode.None;
-
-			// Determine coordinates
-			SizeF textsize = g.MeasureString(Text, this.ListView.Font, bounds.Width * 2);
-			Rectangle imagerect = new Rectangle(bounds.Left + ((bounds.Width - General.Map.Data.Previews.MaxImageWidth) >> 1),
-				bounds.Top + ((bounds.Height - General.Map.Data.Previews.MaxImageHeight - (int)textsize.Height) >> 1),
-				General.Map.Data.Previews.MaxImageWidth, General.Map.Data.Previews.MaxImageHeight);
-			PointF textpos = new PointF(bounds.Left + (bounds.Width * 0.5f), bounds.Bottom - textsize.Height - 2);
-
-			// Determine colors
-			if(this.Selected)
+			if(bmp == null) return;
+
+			var iw = bmp.Width;
+			var ih = bmp.Height;
+
+			if(iw > w && iw >= ih)
 			{
-				// Highlighted
-				backcolor = new LinearGradientBrush(new Point(0, bounds.Top - 1), new Point(0, bounds.Bottom + 1),
-					AdjustedColor(SystemColors.Highlight, 0.2f),
-					AdjustedColor(SystemColors.Highlight, -0.1f));
-				forecolor = new SolidBrush(SystemColors.HighlightText);
+				ih = (int)Math.Floor(h * (ih / (float)iw));
+				iw = w;
+			}
+			else if(ih > h)
+			{
+				iw = (int)Math.Floor(w * (iw / (float)ih));
+				ih = h;
+			}
+
+			int ix = (iw < w ? x + (w - iw) / 2 : x + 1);
+			int iy = (ih < h ? y + (h - ih) / 2 : y + 1);
+
+			// Pick colors and brushes
+			Brush bgbrush, fgbrush, selectedbgbrush, selectionbrush;
+			Color bgcolor;
+			Pen selection;
+			if(General.Settings.BlackBrowsers)
+			{
+				bgcolor = Color.Black;
+				bgbrush = Brushes.Black;
+				fgbrush = Brushes.White;
+				selectedbgbrush = Brushes.Gray;
+				selection = Pens.Red;
+				selectionbrush = Brushes.Red;
 			}
 			else
 			{
-				// Normal
-				backcolor = new SolidBrush(base.ListView.BackColor);
-				forecolor = new SolidBrush(base.ListView.ForeColor);
+				bgcolor = SystemColors.Window;
+				bgbrush = SystemBrushes.Window;
+				fgbrush = SystemBrushes.ControlText;
+				selectedbgbrush = SystemBrushes.ActiveCaption;
+				selection = SystemPens.HotTrack;
+				selectionbrush = SystemBrushes.HotTrack;
 			}
 
-			// Draw!
-			g.FillRectangle(backcolor, bounds);
-			Icon.DrawPreview(g, imagerect.Location);
-			g.DrawString(Text, this.ListView.Font, forecolor, textpos, format);
+			// Item bg
+			g.FillRectangle(bgbrush, x - 3, y - 3, w + 6, h + 10 + SystemFonts.MessageBoxFont.Height);
 
-			//mxd. Dispose brushes
-			backcolor.Dispose();
-			forecolor.Dispose();
+			// Selected image bg
+			if(selected) g.FillRectangle(selectedbgbrush, x - 1, y - 1, w + 2, h + 2);
 
-			//mxd. Draw size label?
-			if(General.Settings.ShowTextureSizes && !string.IsNullOrEmpty(imagesize))
+			// Image
+			g.DrawImage(bmp, ix, iy, iw, ih);
+
+			// Frame
+			if(selected)
 			{
-				// Setup
-				using(Font sizefont = new Font(this.ListView.Font.FontFamily, this.ListView.Font.SizeInPoints - 1))
-				{
-					textsize = g.MeasureString(imagesize, sizefont, bounds.Width * 2);
-					textpos = new PointF(bounds.Left + textsize.Width / 2, bounds.Top + 1);
-					imagerect = new Rectangle(bounds.Left + 1, bounds.Top + 1, (int)textsize.Width, (int)textsize.Height);
-
-					// Draw
-					using(SolidBrush labelbg = new SolidBrush(Color.FromArgb(196, base.ListView.ForeColor)))
-					{
-						g.FillRectangle(labelbg, imagerect);
-					}
-					using(SolidBrush labelcolor = new SolidBrush(base.ListView.BackColor))
-					{
-						g.DrawString(imagesize, sizefont, labelcolor, textpos, format);
-					}
-				}
+				g.DrawRectangle(selection, x - 1, y - 1, w + 1, h + 1);
+				g.DrawRectangle(selection, x - 2, y - 2, w + 3, h + 3);
+			}
+			else
+			{
+				g.DrawRectangle(Pens.Gray, x - 2, y - 2, w + 3, h + 3);
 			}
-		}
 
-		// This brightens or darkens a color
-		private static Color AdjustedColor(Color c, float amount)
-		{
-			Color4 cc = new Color4(c);
-			
-			// Adjust color
-			cc.Red = Saturate((cc.Red * (1f + amount)) + (amount * 0.5f));
-			cc.Green = Saturate((cc.Green * (1f + amount)) + (amount * 0.5f));
-			cc.Blue = Saturate((cc.Blue * (1f + amount)) + (amount * 0.5f));
-			
-			// Return result
-			return Color.FromArgb(cc.ToArgb());
-		}
+			// Image name
+			g.DrawString(TextureName, SystemFonts.MessageBoxFont, (selected ? selectionbrush : fgbrush), x - 2, y + h + 3);
 
-		// This clamps a value between 0 and 1
-		private static float Saturate(float v)
-		{
-			if(v < 0f) return 0f; else if(v > 1f) return 1f; else return v;
-		}
+			// Image size
+			if(General.Settings.ShowTextureSizes && icon.IsPreviewLoaded && itemtype == ImageBrowserItemType.IMAGE)
+			{
+				string imagesize = Math.Abs(icon.ScaledWidth) + "x" + Math.Abs(icon.ScaledHeight);
+				SizeF textsize = g.MeasureString(imagesize, SystemFonts.MessageBoxFont);
+				textsize.Width += 2;
+				textsize.Height -= 2;
 
-		//mxd
-		private void UpdateName() 
-		{
-			Text = (showfullname ? Icon.DisplayName : Icon.ShortName);
-			if(General.Settings.ShowTextureSizes && Icon.IsPreviewLoaded)
-				imagesize = Math.Abs(Icon.ScaledWidth) + "x" + Math.Abs(Icon.ScaledHeight);
+				// Draw bg
+				using(Brush bg = new SolidBrush(Color.FromArgb(192, bgcolor)))
+				{
+					g.FillRectangle(bg, x, y, textsize.Width, textsize.Height);
+				}
+
+				// Draw text
+				g.DrawString(imagesize, SystemFonts.MessageBoxFont, (selected ? selectionbrush : fgbrush), x, y - 1);
+			}
 		}
 
 		// Comparer
 		public int CompareTo(ImageBrowserItem other)
 		{
-			return this.Text.ToUpperInvariant().CompareTo(other.Text.ToUpperInvariant());
+			if(itemtype != other.itemtype) return ((int)itemtype).CompareTo((int)other.itemtype);
+			return this.TextureName.ToUpperInvariant().CompareTo(other.TextureName.ToUpperInvariant());
 		}
 
 		#endregion
diff --git a/Source/Core/Controls/ImageSelectorControl.Designer.cs b/Source/Core/Controls/ImageSelectorControl.Designer.cs
index 90e45cff0..dd3eebedd 100644
--- a/Source/Core/Controls/ImageSelectorControl.Designer.cs
+++ b/Source/Core/Controls/ImageSelectorControl.Designer.cs
@@ -30,7 +30,7 @@ namespace CodeImp.DoomBuilder.Controls
 		{
 			this.components = new System.ComponentModel.Container();
 			this.preview = new System.Windows.Forms.Panel();
-			this.labelSize = new System.Windows.Forms.Label();
+			this.labelSize = new CodeImp.DoomBuilder.Controls.TransparentLabel();
 			this.timer = new System.Windows.Forms.Timer(this.components);
 			this.tooltip = new System.Windows.Forms.ToolTip(this.components);
 			this.togglefullname = new System.Windows.Forms.Button();
@@ -137,7 +137,7 @@ namespace CodeImp.DoomBuilder.Controls
 
 		protected System.Windows.Forms.Panel preview;
 		protected CodeImp.DoomBuilder.Controls.AutoSelectTextbox name;
-		private System.Windows.Forms.Label labelSize;
+		private CodeImp.DoomBuilder.Controls.TransparentLabel labelSize;
 		protected System.Windows.Forms.Timer timer;
 		private System.Windows.Forms.ToolTip tooltip;
 		private ConfigurablePictureBox imagebox;
diff --git a/Source/Core/Controls/ImageSelectorControl.cs b/Source/Core/Controls/ImageSelectorControl.cs
index 46f39d460..40fcf8e7c 100644
--- a/Source/Core/Controls/ImageSelectorControl.cs
+++ b/Source/Core/Controls/ImageSelectorControl.cs
@@ -40,14 +40,12 @@ namespace CodeImp.DoomBuilder.Controls
 		private ImageData image; //mxd
 		private string previousimagename; //mxd
 		protected bool multipletextures; //mxd
-		protected bool usepreviews = true; //mxd
 		
 		#endregion
 
 		#region ================== Properties
 		
 		public string TextureName { get { return name.Text; } set { name.Text = value; } }
-		public bool UsePreviews { get { return usepreviews; } set { usepreviews = value; } } //mxd
 
 		[Browsable(false)]
 		public bool MultipleTextures { get { return multipletextures; } set { multipletextures = value; } }
@@ -68,7 +66,7 @@ namespace CodeImp.DoomBuilder.Controls
 		{
 			// set the max length of texture names
 			name.MaxLength = General.Map.Config.MaxTextureNameLength;
-			if(General.Settings.CapitalizeTextureNames) this.name.CharacterCasing = CharacterCasing.Upper; //mxd
+			if(!General.Map.Options.UseLongTextureNames) this.name.CharacterCasing = CharacterCasing.Upper; //mxd
 			labelSize.BackColor = Color.FromArgb(196, labelSize.BackColor);
 		}
 		
@@ -101,7 +99,12 @@ namespace CodeImp.DoomBuilder.Controls
 			switch(button)
 			{
 				case MouseButtons.Right: name.Text = "-"; break;
-				case MouseButtons.Left: name.Text = BrowseImage(name.Text); break;
+				case MouseButtons.Left:
+					// We need to change CharacterCasing before applying the text, so let's hack around a bit...
+					string newname = BrowseImage(name.Text);
+					name.CharacterCasing = (IsLongTextureName(newname) ? CharacterCasing.Normal : CharacterCasing.Upper);
+					name.Text = newname;
+					break;
 			}
 		}
 		
@@ -155,7 +158,16 @@ namespace CodeImp.DoomBuilder.Controls
 		private void togglefullname_Click(object sender, EventArgs e)
 		{
 			// Toggle between short and full name
-			name.Text = (name.Text == image.ShortName ? image.Name : image.ShortName);
+			if(string.Compare(name.Text, image.ShortName, StringComparison.OrdinalIgnoreCase) == 0)
+			{
+				name.CharacterCasing = CharacterCasing.Normal;
+				name.Text = image.Name;
+			}
+			else
+			{
+				name.CharacterCasing = CharacterCasing.Upper;
+				name.Text = image.ShortName;
+			}
 
 			// Update icon and tooltip
 			UpdateToggleImageNameButton(image);
@@ -208,10 +220,26 @@ namespace CodeImp.DoomBuilder.Controls
 			labelSize.Text = (width > 0 && height > 0) ? width + "x" + height : string.Empty;
 			ImageSelectorControl_EnabledChanged(this, EventArgs.Empty);
 		}
+
+		//mxd
+		private bool IsLongTextureName(string imagename)
+		{
+			if(!General.Map.Config.UseLongTextureNames || string.IsNullOrEmpty(imagename) || imagename == "-") 
+				return false;
+
+			ImageData texture = GetImageData(imagename);
+			if(texture == null || !texture.HasLongName) return false;
+
+			return string.Compare(imagename, texture.ShortName, StringComparison.OrdinalIgnoreCase) != 0;
+		}
+
 		
 		// This must determine and return the image to show
 		protected abstract Image FindImage(string imagename);
 
+		//mxd. This gets ImageData by name...
+		protected abstract ImageData GetImageData(string imagename);
+
 		// This must show the image browser and return the selected texture name
 		protected abstract string BrowseImage(string imagename);
 
@@ -228,7 +256,7 @@ namespace CodeImp.DoomBuilder.Controls
 
 			// Update icon and tooltip
 			togglefullname.Visible = true;
-			if(image.ShortName == name.Text)
+			if(string.Compare(image.ShortName, name.Text, StringComparison.OrdinalIgnoreCase) == 0)
 			{
 				togglefullname.Image = Properties.Resources.Expand;
 				tooltip.SetToolTip(togglefullname, "Switch to full name");
diff --git a/Source/Core/Controls/ImageSelectorPanel.cs b/Source/Core/Controls/ImageSelectorPanel.cs
new file mode 100644
index 000000000..0cb327636
--- /dev/null
+++ b/Source/Core/Controls/ImageSelectorPanel.cs
@@ -0,0 +1,645 @@
+#region ================== Namespaces
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.Linq;
+using System.Windows.Forms;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.Controls
+{
+	//mxd. Based on (but heavily reworked since) TextureListPanel from Sledge (https://github.com/LogicAndTrick/sledge)
+	internal class ImageSelectorPanel : Panel
+	{
+		#region ================== Constants
+
+		internal const string DEFAULT_GROUP = "[DEFAULT_GROUP]";
+
+		#endregion
+
+		#region ================== Variables
+
+		private VScrollBar scrollbar;
+		private List<ImageBrowserItem> items;
+		private List<ImageBrowserItem> selection;
+		private List<Rectangle> rectangles;
+		private ImageBrowserItem lastselecteditem;
+		private int imagesize = 128;
+		private string title;
+		private int titleheight = SystemFonts.MessageBoxFont.Height + 6;
+
+		//mxd. Tooltips
+		private ToolTip tooltip;
+		private Point lasttooltippos;
+		private const int tooltipreshowdistance = 48;
+
+		//mxd. Textures cache
+		private static Dictionary<int, Dictionary<long, Image>> texturecache = new Dictionary<int, Dictionary<long, Image>>(); // <imagesize, < texture longname, preview image>>
+
+		// Selection
+		private bool allowselection;
+		private bool allowmultipleselection;
+
+		#endregion
+
+		#region ================== Event handlers
+
+		public delegate void ItemSelectedEventHandler(object sender, ImageBrowserItem item);
+		public delegate void SelectionChangedEventHandler(object sender, List<ImageBrowserItem> selection);
+
+		/*public event ItemSelectedEventHandler ItemSelected;
+		private void OnItemSelected(ImageBrowserItem item)
+		{
+			if(ItemSelected != null) ItemSelected(this, item);
+		}*/
+
+		public event SelectionChangedEventHandler SelectionChanged;
+		private void OnSelectionChanged(List<ImageBrowserItem> selection)
+		{
+			if(SelectionChanged != null) SelectionChanged(this, selection);
+		}
+
+		public event ItemSelectedEventHandler ItemDoubleClicked;
+		private void OnItemDoubleClicked(ImageBrowserItem item)
+		{
+			if(ItemDoubleClicked != null) ItemDoubleClicked(this, item);
+		}
+
+		#endregion
+
+		#region ================== Properties
+
+		public bool HideSelection
+		{
+			get { return !allowselection; }
+			set
+			{
+				allowselection = !value;
+				if(!allowselection && selection.Count > 0)
+				{
+					selection.Clear();
+					Refresh();
+				}
+			}
+		}
+
+		public bool MultiSelect
+		{
+			get { return allowmultipleselection; }
+			set
+			{
+				allowmultipleselection = value;
+				if(!allowmultipleselection && selection.Count > 0)
+				{
+					var first = selection[0];
+					selection.Clear();
+					selection.Add(first);
+					Refresh();
+				}
+			}
+		}
+
+		public int ImageSize
+		{
+			get { return imagesize; }
+			set
+			{
+				imagesize = value;
+				UpdateRectangles();
+				if(selection.Count > 0) ScrollToItem(selection[0]);
+			}
+		}
+
+		public List<ImageBrowserItem> Items { get { return items; } }
+		public List<ImageBrowserItem> SelectedItems { get { return selection; } }
+		public string Title { get { return title; } set { title = value; } }
+
+		#endregion
+
+		#region ================== Constructor / Disposer
+
+		public ImageSelectorPanel()
+		{
+			VScroll = true;
+			AutoScroll = true;
+			DoubleBuffered = true;
+
+			scrollbar = new VScrollBar { Dock = DockStyle.Right };
+			scrollbar.ValueChanged += (sender, e) => Refresh();
+			tooltip = new ToolTip(); //mxd
+			items = new List<ImageBrowserItem>();
+			selection = new List<ImageBrowserItem>();
+			imagesize = 128;
+			rectangles = new List<Rectangle>();
+			title = "Default group";
+
+			Controls.Add(scrollbar);
+		}
+
+		protected override void Dispose(bool disposing)
+		{
+			if(disposing) Clear();
+			base.Dispose(disposing);
+		}
+
+		#endregion
+
+		#region ================== Add/Remove/Get Textures
+
+		//mxd
+		public void Clear()
+		{
+			selection.Clear();
+			items.Clear();
+			lastselecteditem = null;
+			rectangles.Clear();
+
+			OnSelectionChanged(selection);
+			Refresh();
+		}
+
+		//mxd
+		public void ClearSelection()
+		{
+			selection.Clear();
+			lastselecteditem = null;
+
+			OnSelectionChanged(selection);
+			Refresh();
+		}
+
+		public void SetItems(IEnumerable<ImageBrowserItem> items)
+		{
+			this.items.Clear();
+			lastselecteditem = null;
+			selection.Clear();
+			this.items.AddRange(items);
+
+			OnSelectionChanged(selection);
+			UpdateRectangles();
+		}
+
+		public void SetSelectedItem(ImageBrowserItem item)
+		{
+			SetSelectedItems(new List<ImageBrowserItem> { item } );
+		}
+
+		public void SetSelectedItems(List<ImageBrowserItem> items)
+		{
+			selection.Clear();
+			if(items.Count > 0)
+			{
+				selection.AddRange(items);
+				ScrollToItem(items[0]); //mxd
+				Refresh(); //mxd
+			}
+			OnSelectionChanged(selection);
+		}
+
+		public void ScrollToItem(ImageBrowserItem item)
+		{
+			int index = items.IndexOf(item);
+			if(index < 0) return;
+
+			Rectangle rec = rectangles[index];
+
+			//mxd. Already visible?
+			int ymin = scrollbar.Value - titleheight;
+			int ymax = ymin + this.ClientRectangle.Height + titleheight;
+			if(rec.Top - 3 >= ymin && rec.Bottom + 3 <= ymax) return;
+
+			int yscroll = Math.Max(0, Math.Min(rec.Top - titleheight - 3, scrollbar.Maximum - ClientRectangle.Height));
+			scrollbar.Value = yscroll;
+			Refresh();
+		}
+
+		public void SelectNextItem(SearchDirectionHint dir)
+		{
+			if(!allowselection) return;
+
+			if(selection.Count == 0)
+			{
+				if(items.Count > 0) SetSelectedItem(items[0]);
+				return;
+			}
+
+			int targetindex = items.IndexOf(selection[0]);
+			Rectangle rect = rectangles[targetindex];
+			int index, newindex, tx, cx, cy;
+
+			switch(dir)
+			{
+				case SearchDirectionHint.Right:
+					// Just select the next item
+					if(targetindex < items.Count - 1) SetSelectedItem(items[targetindex + 1]);
+					break;
+
+				case SearchDirectionHint.Left:
+					// Just select the previous item
+					if(targetindex > 0) SetSelectedItem(items[targetindex - 1]);
+					break;
+
+				case SearchDirectionHint.Up:
+					// Skip current row...
+					index = targetindex - 1;
+					if(index < 0) break;
+					while(index > 0)
+					{
+						if(rectangles[index].Y != rect.Y) break;
+						index--;
+					}
+
+					// Check upper row for best match
+					tx = rect.X + rect.Width / 2;
+					cx = int.MaxValue;
+					cy = rectangles[index].Y;
+					newindex = int.MaxValue;
+
+					while(index > 0 && rectangles[index].Y == cy)
+					{
+						int ccx = Math.Abs(rectangles[index].X + rectangles[index].Width / 2 - tx);
+						if(ccx < cx)
+						{
+							cx = ccx;
+							newindex = index;
+						}
+						index--;
+					}
+
+					// Select item
+					if(newindex != int.MaxValue) SetSelectedItem(items[newindex]);
+					break;
+
+				case SearchDirectionHint.Down:
+					// Skip current row...
+					index = targetindex + 1;
+					if(index > rectangles.Count - 1) break;
+					while(index < rectangles.Count - 1)
+					{
+						if(rectangles[index].Y != rect.Y) break;
+						index++;
+					}
+
+					// Check upper row for best match
+					tx = rect.X + rect.Width / 2;
+					cx = int.MaxValue;
+					cy = rectangles[index].Y;
+					newindex = int.MaxValue;
+
+					while(index < rectangles.Count - 1 && rectangles[index].Y == cy)
+					{
+						int ccx = Math.Abs(rectangles[index].X + rectangles[index].Width / 2 - tx);
+						if(ccx < cx)
+						{
+							cx = ccx;
+							newindex = index;
+						}
+						index++;
+					}
+
+					// Select item
+					if(newindex != int.MaxValue) SetSelectedItem(items[newindex]);
+					break;
+			}
+		}
+
+		protected override void OnMouseDoubleClick(MouseEventArgs e)
+		{
+			base.OnMouseDoubleClick(e);
+			if(General.Interface.CtrlState || General.Interface.ShiftState || selection.Count != 1)
+				return;
+
+			int index = GetIndexAt(e.X, scrollbar.Value + e.Y);
+			if(index == -1) return;
+
+			OnItemDoubleClicked(items[index]);
+		}
+
+		protected override void OnMouseDown(MouseEventArgs e)
+		{
+			base.OnMouseDown(e);
+			this.Focus();
+
+			if(!allowselection) return;
+			if(!allowmultipleselection || !General.Interface.CtrlState)
+				selection.Clear();
+
+			int x = e.X;
+			int y = scrollbar.Value + e.Y;
+
+			int clickedIndex = GetIndexAt(x, y);
+			var item = (clickedIndex >= 0 && clickedIndex < items.Count ? items[clickedIndex] : null);
+
+			if(item == null)
+			{
+				selection.Clear();
+			}
+			else if(allowmultipleselection && General.Interface.CtrlState && selection.Contains(item))
+			{
+				selection.Remove(item);
+				lastselecteditem = null;
+			}
+			else if(allowmultipleselection && General.Interface.ShiftState && lastselecteditem != null)
+			{
+				int bef = items.IndexOf(lastselecteditem);
+				var start = Math.Min(bef, clickedIndex);
+				var count = Math.Abs(clickedIndex - bef) + 1;
+				selection.AddRange(items.GetRange(start, count).Where(i => !selection.Contains(i)));
+			}
+			else
+			{
+				selection.Add(item);
+				lastselecteditem = item;
+			}
+
+			OnSelectionChanged(selection);
+			Refresh();
+		}
+
+		protected override void OnMouseEnter(EventArgs e)
+		{
+			Focus();
+			base.OnMouseEnter(e);
+		}
+
+		//mxd
+		protected override void OnMouseMove(MouseEventArgs e)
+		{
+			base.OnMouseMove(e);
+
+			int index = GetIndexAt(e.X, scrollbar.Value + e.Y);
+			if(index == -1 || items[index].ItemType != ImageBrowserItemType.IMAGE || string.IsNullOrEmpty(items[index].ToolTip))
+			{
+				if(tooltip.Active) tooltip.Hide(this);
+			}
+			else if(!tooltip.Active || tooltip.GetToolTip(this) != items[index].ToolTip
+				|| Math.Abs(lasttooltippos.X - e.Location.X) > tooltipreshowdistance
+				|| Math.Abs(lasttooltippos.Y - e.Location.Y) > tooltipreshowdistance)
+			{
+				Point pos = new Point(e.Location.X, e.Location.Y + Cursor.Size.Height + 4);
+				tooltip.Show(items[index].ToolTip, this, pos, 999999);
+				lasttooltippos = e.Location;
+			}
+		}
+
+		public int GetIndexAt(int x, int y)
+		{
+			const int pad = 3;
+			int font = 4 + SystemFonts.MessageBoxFont.Height;
+
+			for(var i = 0; i < rectangles.Count; i++)
+			{
+				var rec = rectangles[i];
+				if(rec.Left - pad <= x
+					&& rec.Right + pad >= x
+					&& rec.Top - pad <= y
+					&& rec.Bottom + pad + font >= y)
+				{
+					return i;
+				}
+			}
+
+			return -1;
+		}
+
+		#endregion
+
+		#region ================== Scrolling
+
+		private void ScrollByAmount(int value)
+		{
+			int newvalue = Math.Max(0, scrollbar.Value + value);
+			scrollbar.Value = Math.Min(newvalue, Math.Max(0, scrollbar.Maximum - ClientRectangle.Height));
+		}
+
+		protected override void OnMouseWheel(MouseEventArgs e)
+		{
+			base.OnMouseWheel(e);
+			ScrollByAmount(scrollbar.SmallChange * (e.Delta / -120));
+		}
+
+		//mxd. Otherwise arrow keys won't be handled by OnKeyDown
+		protected override bool IsInputKey(Keys keyData)
+		{
+			switch(keyData)
+			{
+				case Keys.Right: case Keys.Left: 
+				case Keys.Up: case Keys.Down: 
+				case Keys.Return: return true;
+			}
+
+			return base.IsInputKey(keyData);
+		}
+
+		protected override void OnKeyDown(KeyEventArgs e)
+		{
+			ProcessKeyDown(e);
+			base.OnKeyDown(e);
+		}
+
+		internal bool ProcessKeyDown(KeyEventArgs e)
+		{
+			switch(e.KeyCode)
+			{
+				//mxd. Cursor keys
+				case Keys.Left: SelectNextItem(SearchDirectionHint.Left); return true;
+				case Keys.Right: SelectNextItem(SearchDirectionHint.Right); return true;
+				case Keys.Up: SelectNextItem(SearchDirectionHint.Up); return true;
+				case Keys.Down: SelectNextItem(SearchDirectionHint.Down); return true;
+
+				case Keys.PageDown: ScrollByAmount(scrollbar.LargeChange); return true;
+				case Keys.PageUp: ScrollByAmount(-scrollbar.LargeChange); return true;
+				case Keys.End: ScrollByAmount(int.MaxValue); return true;
+				case Keys.Home: ScrollByAmount(-int.MaxValue); return true;
+				
+				case Keys.Enter:
+					if(selection.Count > 0)
+					{
+						OnItemDoubleClicked(selection[0]);
+						return true;
+					}
+					break;
+
+			}
+
+			return false;
+		}
+
+		/*protected override void OnMouseEnter(EventArgs e)
+		{
+			Focus();
+			base.OnMouseEnter(e);
+		}*/
+
+		#endregion
+
+		#region ================== Updating Rectangles & Dimensions
+
+		protected override void OnResize(EventArgs e)
+		{
+			base.OnResize(e);
+			UpdateRectangles();
+
+			//mxd
+			if(selection.Count > 0) ScrollToItem(selection[0]);
+		}
+
+		private void UpdateRectangles()
+		{
+			int w = ClientRectangle.Width - scrollbar.Width;
+			const int pad = 3;
+			int font = 4 + SystemFonts.MessageBoxFont.Height;
+			int cx = 0;
+			int cy = titleheight;
+			int my = 0;
+			rectangles.Clear();
+
+			foreach(var ti in items)
+			{
+				Image preview = GetPreview(ti, imagesize);
+				
+				int rw = w - cx;
+				int wid = (imagesize > 0 ? imagesize : preview.Width) + pad + pad;
+				int hei = (imagesize > 0 ? imagesize : preview.Height) + pad + pad + font;
+				
+				if(rw < wid)
+				{
+					// New row
+					cx = 0;
+					cy += my;
+					my = 0;
+				}
+
+				my = Math.Max(my, hei);
+				var rect = new Rectangle(cx + pad, cy + pad, wid - pad - pad, hei - pad - pad - font);
+				rectangles.Add(rect);
+				cx += wid;
+			}
+
+			if(rectangles.Count > 0)
+			{
+				scrollbar.Maximum = cy + my;
+				scrollbar.SmallChange = (imagesize > 0 ? imagesize : 128) + pad + pad + font;
+				scrollbar.LargeChange = ClientRectangle.Height;
+				scrollbar.Visible = (scrollbar.Maximum > ClientRectangle.Height);
+
+				if(scrollbar.Value > scrollbar.Maximum - ClientRectangle.Height)
+				{
+					scrollbar.Value = Math.Max(0, scrollbar.Maximum - ClientRectangle.Height);
+				}
+			}
+			else
+			{
+				scrollbar.Visible = false;
+			}
+
+			Refresh();
+		}
+
+		#endregion
+
+		#region ================== Rendering
+
+		protected override void OnPaint(PaintEventArgs e)
+		{
+			base.OnPaint(e);
+			DrawTextures(e.Graphics);
+		}
+
+		private void DrawTextures(Graphics g)
+		{
+			// Draw items
+			if(items.Count > 0)
+			{
+				int y = scrollbar.Value;
+				int height = ClientRectangle.Height - titleheight;
+
+				for(var i = 0; i < items.Count; i++)
+				{
+					Rectangle rec = rectangles[i];
+					if(rec.Bottom < y) continue;
+					if(rec.Top > y + height) break;
+
+					Image bmp = GetPreview(items[i], imagesize);
+					items[i].Draw(g, bmp, rec.X, rec.Y - y, rec.Width, rec.Height, selection.Contains(items[i]));
+				}
+			}
+
+			// Draw title on top of items
+			if(title != DEFAULT_GROUP)
+			{
+				// Draw group name bg
+				bool blackbrowsers = (General.Settings != null && General.Settings.BlackBrowsers);
+				Color bgcolor = (blackbrowsers ? Color.Gray : SystemColors.Control);
+				using(Brush bg = new SolidBrush(Color.FromArgb(192, bgcolor)))
+				{
+					int scrollwidth = (scrollbar.Visible ? scrollbar.Width : 0);
+					g.FillRectangle(bg, 2, 2, ClientRectangle.Width - scrollwidth - 4, SystemFonts.MessageBoxFont.Height);
+				}
+
+				// Draw group name
+				Brush fgbrush = (blackbrowsers ? Brushes.White : SystemBrushes.ControlText);
+				g.DrawString(title, SystemFonts.MessageBoxFont, fgbrush, 2, 2);
+			}
+		}
+
+		#endregion
+
+		#region ================== Image Caching
+
+		private static Image GetPreview(ImageBrowserItem item, int imagesize)
+		{
+			if(!item.IsPreviewLoaded) return item.Icon.GetPreview();
+			if(!texturecache.ContainsKey(imagesize)) texturecache.Add(imagesize, new Dictionary<long, Image>());
+
+			// Generate preview?
+			if(!texturecache[imagesize].ContainsKey(item.Icon.LongName))
+			{
+				Image img = item.Icon.GetPreview();
+				
+				// Determine preview size
+				float scalex, scaley;
+				if(item.ItemType == ImageBrowserItemType.IMAGE)
+				{
+					scalex = (imagesize == 0 ? 1.0f : (imagesize / (float)img.Width));
+					scaley = (imagesize == 0 ? 1.0f :(imagesize / (float)img.Height));
+				}
+				else
+				{
+					// Don't upscale folder icons
+					scalex = (imagesize == 0 ? 1.0f : ((img.Width > imagesize) ? (imagesize / (float)img.Width) : 1.0f));
+					scaley = (imagesize == 0 ? 1.0f : ((img.Height > imagesize) ? (imagesize / (float)img.Height) : 1.0f));
+				}
+				
+				float scale = Math.Min(scalex, scaley);
+				int previewwidth = (int)(img.Width * scale);
+				int previewheight = (int)(img.Height * scale);
+				if(previewwidth < 1) previewwidth = 1;
+				if(previewheight < 1) previewheight = 1;
+
+				// Make new image
+				Bitmap preview = new Bitmap(previewwidth, previewheight, PixelFormat.Format32bppArgb);
+				using(Graphics g = Graphics.FromImage(preview))
+				{
+					g.PageUnit = GraphicsUnit.Pixel;
+					g.InterpolationMode = InterpolationMode.NearestNeighbor;
+					g.PixelOffsetMode = PixelOffsetMode.None;
+
+					g.DrawImage(img, new Rectangle(0, 0, previewwidth, previewheight));
+				}
+
+				texturecache[imagesize][item.Icon.LongName] = preview;
+			}
+
+			// Get preview
+			return texturecache[imagesize][item.Icon.LongName];
+		}
+
+		#endregion
+	}
+}
diff --git a/Source/Core/Controls/LinedefInfoPanel.cs b/Source/Core/Controls/LinedefInfoPanel.cs
index 4c6cfb257..759423411 100644
--- a/Source/Core/Controls/LinedefInfoPanel.cs
+++ b/Source/Core/Controls/LinedefInfoPanel.cs
@@ -591,7 +591,7 @@ namespace CodeImp.DoomBuilder.Controls
 		private static void UpdateTexturePanel(Panel panel, string texturename, Label texturenamelabel, Label sizelabel, int maxlabelright, Panel image, int sizeref, bool extendedinfoshown, bool required)
 		{
 			// Set texture name
-			texturenamelabel.Text = texturename;
+			texturenamelabel.Text = (texturename.Length > DataManager.CLASIC_IMAGE_NAME_LENGTH ? texturename : texturename.ToUpperInvariant());
 
 			// And image
 			DisplayTextureImage(image, sizelabel, texturename, required);
diff --git a/Source/Core/Controls/SectorInfoPanel.cs b/Source/Core/Controls/SectorInfoPanel.cs
index e114e7b6a..400541b3b 100644
--- a/Source/Core/Controls/SectorInfoPanel.cs
+++ b/Source/Core/Controls/SectorInfoPanel.cs
@@ -20,6 +20,7 @@ using System;
 using System.Drawing;
 using System.Globalization;
 using System.Windows.Forms;
+using CodeImp.DoomBuilder.IO;
 using CodeImp.DoomBuilder.Map;
 using CodeImp.DoomBuilder.Data;
 using CodeImp.DoomBuilder.Rendering;
@@ -67,8 +68,8 @@ namespace CodeImp.DoomBuilder.Controls
 			floor.Text = s.FloorHeight.ToString();
 			height.Text = sheight.ToString();
 			brightness.Text = s.Brightness.ToString();
-			floorname.Text = s.FloorTexture;
-			ceilingname.Text = s.CeilTexture;
+			floorname.Text = (s.FloorTexture.Length > DataManager.CLASIC_IMAGE_NAME_LENGTH ? s.FloorTexture : s.FloorTexture.ToUpperInvariant());
+			ceilingname.Text = (s.CeilTexture.Length > DataManager.CLASIC_IMAGE_NAME_LENGTH ? s.CeilTexture : s.CeilTexture.ToUpperInvariant());
 
 			//mxd. Set tags
 			if(s.Tags.Count > 1)
diff --git a/Source/Core/Controls/TextureSelectorControl.cs b/Source/Core/Controls/TextureSelectorControl.cs
index 9f5d580c6..f2122be9c 100644
--- a/Source/Core/Controls/TextureSelectorControl.cs
+++ b/Source/Core/Controls/TextureSelectorControl.cs
@@ -75,15 +75,19 @@ namespace CodeImp.DoomBuilder.Controls
 				if(string.IsNullOrEmpty(texture.FilePathName) || texture is UnknownImage) DisplayImageSize(0, 0); //mxd
 				else DisplayImageSize(texture.ScaledWidth, texture.ScaledHeight); //mxd
 
-				if(usepreviews && !texture.IsPreviewLoaded) timer.Start(); //mxd
-				else if(!texture.IsImageLoaded) texture.LoadImage(); //mxd. In some cases the image may never me loaded by the DataManager
+				if(!texture.IsPreviewLoaded) timer.Start(); //mxd
 
 				// Set the image
-				// mxd. GetPreview() returns a copy of preview, GetBitmap() returns actual bitmap
-				return (usepreviews ? texture.GetPreview() : new Bitmap(texture.GetBitmap()));
+				return texture.GetPreview();
 			}
 		}
 
+		//mxd. This gets ImageData by name...
+		protected override ImageData GetImageData(string imagename)
+		{
+			return General.Map.Data.GetTextureImage(imagename);
+		}
+
 		// This browses for a texture
 		protected override string BrowseImage(string imagename) 
 		{
diff --git a/Source/Core/Controls/TransparentLabel.cs b/Source/Core/Controls/TransparentLabel.cs
new file mode 100644
index 000000000..a49c4d88a
--- /dev/null
+++ b/Source/Core/Controls/TransparentLabel.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Windows.Forms;
+
+namespace CodeImp.DoomBuilder.Controls
+{
+	//mxd. Label, which ignores mouse events
+	internal class TransparentLabel : Label
+	{
+		private const int WM_NCHITTEST = 0x0084;
+		private const int WM_MOUSEHOVER = 0x02A1;
+		private const int HTTRANSPARENT = -1;
+		
+		protected override void WndProc(ref Message m)
+		{
+			switch(m.Msg)
+			{
+				case WM_NCHITTEST:
+				case WM_MOUSEHOVER:
+					m.Result = (IntPtr)HTTRANSPARENT;
+					break;
+
+				default:
+					base.WndProc(ref m);
+					break;
+			}
+		}
+	}
+}
diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs
index 89d333cac..d2ff76632 100644
--- a/Source/Core/Data/DataManager.cs
+++ b/Source/Core/Data/DataManager.cs
@@ -120,6 +120,10 @@ namespace CodeImp.DoomBuilder.Data
 		private ImageData blacktexture; //mxd
 		private ImageData thingtexture; //mxd
 
+		//mxd. Texture Browser images
+		private ImageData foldertexture;
+		private ImageData folderuptexture;
+
 		//mxd. Sky textures
 		private CubeTexture skybox; // GZDoom skybox
 
@@ -180,6 +184,8 @@ namespace CodeImp.DoomBuilder.Data
 		public ImageData WhiteTexture { get { return whitetexture; } }
 		public ImageData BlackTexture { get { return blacktexture; } } //mxd
 		public ImageData ThingTexture { get { return thingtexture; } } //mxd
+		internal ImageData FolderTexture { get { return foldertexture; } } //mxd
+		internal ImageData FolderUpTexture { get { return folderuptexture; } } //mxd
 		public ImageData[] CommentTextures { get { return commenttextures; } } //mxd
 		internal CubeTexture SkyBox { get { return skybox; } } //mxd
 		public List<ThingCategory> ThingCategories { get { return thingcategories; } }
@@ -218,14 +224,20 @@ namespace CodeImp.DoomBuilder.Data
 			blacktexture.CreateTexture(); //mxd
 			unknownimage = new UnknownImage(Properties.Resources.UnknownImage); //mxd. There should be only one!
 
+			//mxd. Textures browser images
+			foldertexture = new ResourceImage("CodeImp.DoomBuilder.Resources.Folder96.png") { UseColorCorrection = false };
+			foldertexture.LoadImage();
+			folderuptexture = new ResourceImage("CodeImp.DoomBuilder.Resources.Folder96Up.png") { UseColorCorrection = false };
+			folderuptexture.LoadImage();
+
 			//mxd. Create comment icons
 			commenttextures = new ImageData[]
 			                  {
-				                  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentRegular.png"),
-								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentInfo.png"),
-								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentQuestion.png"),
-								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentProblem.png"),
-								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentSmile.png"),
+				                  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentRegular.png") { UseColorCorrection = false },
+								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentInfo.png") { UseColorCorrection = false },
+								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentQuestion.png") { UseColorCorrection = false },
+								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentProblem.png") { UseColorCorrection = false },
+								  new ResourceImage("CodeImp.DoomBuilder.Resources.CommentSmile.png") { UseColorCorrection = false },
 			                  };
 
 			//mxd. Load comment icons
@@ -262,6 +274,10 @@ namespace CodeImp.DoomBuilder.Data
 				thingtexture = null; //mxd
 				unknownimage.Dispose(); //mxd
 				unknownimage = null; //mxd
+				foldertexture.Dispose(); //mxd
+				foldertexture = null; //mxd
+				folderuptexture.Dispose(); //mxd
+				folderuptexture = null; //mxd
 				for(int i = 0; i < commenttextures.Length; i++) //mxd
 				{
 					commenttextures[i].Dispose();
diff --git a/Source/Core/Data/FileImage.cs b/Source/Core/Data/FileImage.cs
index 0a59baa43..f4e3019a6 100644
--- a/Source/Core/Data/FileImage.cs
+++ b/Source/Core/Data/FileImage.cs
@@ -129,17 +129,6 @@ namespace CodeImp.DoomBuilder.Data
 
 			this.longname = Lump.MakeLongName(this.name, uselongtexturenames);
 			this.filepathname = filepathname;
-			this.level = virtualname.Split(new[] { Path.AltDirectorySeparatorChar }).Length - 1;
-
-			if(General.Settings.CapitalizeTextureNames && !string.IsNullOrEmpty(this.displayname))
-			{
-				this.displayname = this.displayname.ToUpperInvariant();
-			}
-
-			if(this.displayname.Length > ImageBrowserItem.MAX_NAME_LENGTH)
-			{
-				this.displayname = this.displayname.Substring(0, ImageBrowserItem.MAX_NAME_LENGTH);
-			}
 		}
 
 		// This loads the image
diff --git a/Source/Core/Data/ImageData.cs b/Source/Core/Data/ImageData.cs
index 5d640fb44..41dd4d944 100644
--- a/Source/Core/Data/ImageData.cs
+++ b/Source/Core/Data/ImageData.cs
@@ -58,7 +58,6 @@ namespace CodeImp.DoomBuilder.Data
 		protected bool ismasked; //mxd. If true, has pixels with zero alpha
 		protected bool hasLongName; //mxd. Texture name is longer than DataManager.CLASIC_IMAGE_NAME_LENGTH
 		protected bool hasPatchWithSameName; //mxd
-		protected int level; //mxd. Folder depth of this item
 
 		//mxd. Hashing
 		private static int hashcounter;
@@ -121,7 +120,6 @@ namespace CodeImp.DoomBuilder.Data
 		public virtual float ScaledHeight { get { return (float)Math.Round(height * scale.y); } }
 		public virtual Vector2D Scale { get { return scale; } }
 		public bool WorldPanning { get { return worldpanning; } }
-		public int Level { get { return level; } } //mxd
 
 		#endregion
 
@@ -534,15 +532,15 @@ namespace CodeImp.DoomBuilder.Data
 				else if(loadfailed)
 				{
 					// Draw error bitmap
-					targetpos = new Point(targetpos.X + ((General.Map.Data.Previews.MaxImageWidth - Properties.Resources.Hourglass.Width) >> 1),
-										  targetpos.Y + ((General.Map.Data.Previews.MaxImageHeight - Properties.Resources.Hourglass.Height) >> 1));
+					targetpos = new Point(targetpos.X + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Width) >> 1),
+										  targetpos.Y + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Height) >> 1));
 					target.DrawImageUnscaled(Properties.Resources.Failed, targetpos);
 				}
 				else
 				{
 					// Draw loading bitmap
-					targetpos = new Point(targetpos.X + ((General.Map.Data.Previews.MaxImageWidth - Properties.Resources.Hourglass.Width) >> 1),
-										  targetpos.Y + ((General.Map.Data.Previews.MaxImageHeight - Properties.Resources.Hourglass.Height) >> 1));
+					targetpos = new Point(targetpos.X + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Width) >> 1),
+										  targetpos.Y + ((PreviewManager.MAX_PREVIEW_SIZE - Properties.Resources.Hourglass.Height) >> 1));
 					target.DrawImageUnscaled(Properties.Resources.Hourglass, targetpos);
 				}
 			}
diff --git a/Source/Core/Data/PK3FileImage.cs b/Source/Core/Data/PK3FileImage.cs
index 043c0440f..9ad7c6dbc 100644
--- a/Source/Core/Data/PK3FileImage.cs
+++ b/Source/Core/Data/PK3FileImage.cs
@@ -93,17 +93,6 @@ namespace CodeImp.DoomBuilder.Data
 			this.longname = Lump.MakeLongName(this.name);
 			this.virtualname = filepathname.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
 			this.filepathname = filepathname;
-			this.level = virtualname.Split(new[] { Path.AltDirectorySeparatorChar }).Length - 1;
-
-			if(General.Settings.CapitalizeTextureNames && !string.IsNullOrEmpty(this.displayname)) 
-			{
-				this.displayname = this.displayname.ToUpperInvariant();
-			}
-
-			if(this.displayname.Length > ImageBrowserItem.MAX_NAME_LENGTH) 
-			{
-				this.displayname = this.displayname.Substring(0, ImageBrowserItem.MAX_NAME_LENGTH);
-			}
 		}
 
 		// This loads the image
diff --git a/Source/Core/Data/PreviewManager.cs b/Source/Core/Data/PreviewManager.cs
index 9baa95d3d..8e58ed00d 100644
--- a/Source/Core/Data/PreviewManager.cs
+++ b/Source/Core/Data/PreviewManager.cs
@@ -34,16 +34,12 @@ namespace CodeImp.DoomBuilder.Data
 		private const PixelFormat IMAGE_FORMAT = PixelFormat.Format32bppArgb;
 
 		// Dimensions of a single preview image
-		public static readonly int[] PREVIEW_SIZES = new[] { 48, 64, 80, 96, 112, 128 };
+		public const int MAX_PREVIEW_SIZE = 256; //mxd
 
 		#endregion
 
 		#region ================== Variables
 		
-		// Dimensions of a single preview image
-		private readonly int maxpreviewwidth;
-		private readonly int maxpreviewheight;
-		
 		// Images
 		private List<Bitmap> images;
 		
@@ -57,10 +53,6 @@ namespace CodeImp.DoomBuilder.Data
 		#endregion
 
 		#region ================== Properties
-
-		// Constants
-		public int MaxImageWidth { get { return maxpreviewwidth; } }
-		public int MaxImageHeight { get { return maxpreviewheight; } }
 		
 		// Disposing
 		internal bool IsDisposed { get { return isdisposed; } }
@@ -84,8 +76,6 @@ namespace CodeImp.DoomBuilder.Data
 			// Initialize
 			images = new List<Bitmap>();
 			imageque = new Queue<ImageData>();
-			maxpreviewwidth = PREVIEW_SIZES[General.Settings.PreviewImageSize];
-			maxpreviewheight = PREVIEW_SIZES[General.Settings.PreviewImageSize];
 			
 			// We have no destructor
 			GC.SuppressFinalize(this);
@@ -131,8 +121,8 @@ namespace CodeImp.DoomBuilder.Data
 				}
 				
 				// Determine preview size
-				float scalex = (img.Width > maxpreviewwidth) ? (maxpreviewwidth / (float)imagewidth) : 1.0f;
-				float scaley = (img.Height > maxpreviewheight) ? (maxpreviewheight / (float)imageheight) : 1.0f;
+				float scalex = (img.Width > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imagewidth) : 1.0f;
+				float scaley = (img.Height > MAX_PREVIEW_SIZE) ? (MAX_PREVIEW_SIZE / (float)imageheight) : 1.0f;
 				float scale = Math.Min(scalex, scaley);
 				int previewwidth = (int)(imagewidth * scale);
 				int previewheight = (int)(imageheight * scale);
@@ -193,8 +183,8 @@ namespace CodeImp.DoomBuilder.Data
 			lock(images) { image = images[previewindex]; }
 
 			// Adjust offset for the size of the preview image
-			targetpos.X += (maxpreviewwidth - image.Width) >> 1;
-			targetpos.Y += (maxpreviewheight - image.Height) >> 1;
+			targetpos.X += (MAX_PREVIEW_SIZE - image.Width) >> 1;
+			targetpos.Y += (MAX_PREVIEW_SIZE - image.Height) >> 1;
 			
 			// Draw from atlas to target
 			lock(syncroot)
diff --git a/Source/Core/Data/TEXTURESImage.cs b/Source/Core/Data/TEXTURESImage.cs
index cd9fbe158..fff29db50 100644
--- a/Source/Core/Data/TEXTURESImage.cs
+++ b/Source/Core/Data/TEXTURESImage.cs
@@ -58,7 +58,6 @@ namespace CodeImp.DoomBuilder.Data
 			//mxd
 			SetName(name);
 			this.virtualname = (!string.IsNullOrEmpty(virtualpath) ? virtualpath : "[TEXTURES]") + Path.AltDirectorySeparatorChar + this.name;
-			this.level = virtualname.Split(new[] { Path.AltDirectorySeparatorChar }).Length - 1;
 			this.isFlat = isflat;
 			
 			// We have no destructor
@@ -81,16 +80,6 @@ namespace CodeImp.DoomBuilder.Data
 			
 			base.SetName(name);
 
-			if(General.Settings.CapitalizeTextureNames && !string.IsNullOrEmpty(this.displayname)) 
-			{
-				this.displayname = this.displayname.ToUpperInvariant();
-			}
-
-			if(this.displayname.Length > ImageBrowserItem.MAX_NAME_LENGTH) 
-			{
-				this.displayname = this.displayname.Substring(0, ImageBrowserItem.MAX_NAME_LENGTH);
-			}
-
 			this.shortname = this.displayname.ToUpperInvariant();
 			if(this.shortname.Length > DataManager.CLASIC_IMAGE_NAME_LENGTH) 
 			{
diff --git a/Source/Core/Properties/Resources.Designer.cs b/Source/Core/Properties/Resources.Designer.cs
index 35ba68818..84245c71c 100644
--- a/Source/Core/Properties/Resources.Designer.cs
+++ b/Source/Core/Properties/Resources.Designer.cs
@@ -354,6 +354,20 @@ namespace CodeImp.DoomBuilder.Properties {
             }
         }
         
+        internal static System.Drawing.Bitmap Folder96 {
+            get {
+                object obj = ResourceManager.GetObject("Folder96", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        internal static System.Drawing.Bitmap Folder96Up {
+            get {
+                object obj = ResourceManager.GetObject("Folder96Up", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
         internal static System.Drawing.Bitmap FolderExplore {
             get {
                 object obj = ResourceManager.GetObject("FolderExplore", resourceCulture);
diff --git a/Source/Core/Properties/Resources.resx b/Source/Core/Properties/Resources.resx
index e02f7ac09..437f64227 100644
--- a/Source/Core/Properties/Resources.resx
+++ b/Source/Core/Properties/Resources.resx
@@ -607,4 +607,10 @@
   <data name="WarningLargeText" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\WarningLargeText.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
+  <data name="Folder96" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\Folder96.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="Folder96Up" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\Folder96Up.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
 </root>
\ No newline at end of file
diff --git a/Source/Core/Resources/Folder96.png b/Source/Core/Resources/Folder96.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e63908d3f64c4d8692ab874d875613925d66530
GIT binary patch
literal 9507
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
a>6?u_>FPg2==u+Sf>DrBk*=3C4f}s~l1Xg<

literal 0
HcmV?d00001

diff --git a/Source/Core/Resources/Folder96Up.png b/Source/Core/Resources/Folder96Up.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f98530ab5aaf7646c598919a45a72cc7ec9de75
GIT binary patch
literal 12292
zcma)iQ*b2=u=F{xy)ieoZQItyPByk}Yh!C;V}ldhwl~Q}CwB6G_x-P1_hEWo=4onb
zx@W4RRg|QW5%3WJ006SAjD*^M+4z3~4(2~R_~pq105DI=N{DKBZCv_!|1wy1Kk0nx
z(XP+9`u*>xdo^V%wg|>AMGV}eX*A3cE=y<o?(a@w4XJBcLmo1OiG2)r-mzwZ#8&pB
zNIM5)BQS$rp|~vialmzvse~jby}6BTHBb2-t!4eIyyh)!LyVB00=s@6qxYd|%jZ51
z8NOF9dAsX%AukR}+?=c2;IB6><{;jkztAkBo85rFUO6}*LdQFZUxyAq0IuEBh{g%+
z-oUAw|4&gpP0;6`nLAFMS-{#w;1+E4nN>@{0X!D&yYeGrpyMg~Sp5;nOTtcTlZ(ra
z_Vi}qmx#?CJq>E&-A(gopgR6;f99-ToUM1yLhAIr|D@HE%=)#)qwi<oHmh9S?C5yU
zLILte9trCR(Np(5qMhQ2w{UbIJrHR(a3|+moIgRzh?;z;MI52S)P3PX0Dh{>Y3Li1
z^QffP2b3dgFvsvU7)A9*(s;~qYDet)*$MY^|KMRwvemwNnTuX^d7xt+k`3-N&#ZsN
zQTuOAp?e}^ag?t#!(G=^_onF)y~Ps|lp<IC_Zr>5WC0{Ww|CD8u-;@OHQ;MM2qN$k
z18%^m>`^50`vD34x#QPTH8!aK&ukaU#dGAq)!mKgS#ppS*Nk!(gpey8WXb6#mQn~-
zje`<0;ix?ou43N_uuZSGod?OS=D4DqHla^?dOz`*<jT&+R;aJSIZW|x#NKtvyIZh3
zAcjsx&gLjuW;{-lZjnPsD5t-p1i9mGoGd$?C+A^eLP$P{LkS*k?gO`%sGCF}{KR5|
ztio-fR9**zeJ3ezt4h(#y3l9FA@)Zr;PKsQn0usP_knu3)vkXC9hqk*qfC0yYf@m<
ziO?C&IY>t&|A043uw*YL9d-}6S5zb$F&KYh=HIq)cM~B<=u1+-2>Kw5DKxIRK4kXa
zLgf&{$WM&;g(ZmDKog(NtbiD0?G^r^EwIyj@2kr8#&*)o+>`$;nC`gh86;Ka?pAo7
zLWF443TX2)dC5d^+<D0Cabyy~prn%YQ?EL}vz7r=VJuJm40=e9l;pSAZ$7mCw={v|
z4r>R&aXEi6pj+w;3Y~lY0n}^@O06vP-_qtwWGnknIV4fJ;6S1AeJ`?^hg-th;{HN?
zT2@`n+3ppSiFy2x8;xwcx_Tqm5wZgk`kWT4Ys`G9u~iwxf_Ki^4_nwF*24C~i0^e5
z6Qc1v7$n$a8L|$C@Xmkr=ag&yma*lir*i&Gxrcc7C#rxypva$GgBMUHTBt&!Tm*{N
z#j$Ke=>3o=!a@g%`Jv{rt}p@|jiz(6k3GUTKl^wJVB<gfBD}oLWBmh>MyK@v<fuls
zcLuZiOd6s%DR~W5w|*?hy{sYq3~plB0}6*xXg&J|l+iZ4f(R1T_7SIX;*=w|vog`-
z0)$`ksNx*=uDH8*EE8?!-KNkXg)t#Cw!4n(6i{p~P`Xg2j0~00H^pCZf#uN52^-p@
z?*SX6=5JuOH}i%cS6*VeTUM@rMZ2F=iQ?_Iqak<#9`V7Tu7bDAiXWACJzB8xjL&2Q
zhHQ2TR=3a`mv#{{xeHas-Q&I5aq~13@@VGacS({BG)mJhYA!-*D0bh?4npZ_d#p?5
zcTdGP+wl5Mt4aGnuO{C{yQgXTqGqx7u2lhOV-IOAW?l?&Z4-?!(*nBiBbZctJ2iyV
z*g0YfDQCI1SBtWzpX(78C)#wF9e?r{67-|vG4f;HdSl*5H0Sq;a?nGR@>>Bgz1p3f
zPVZe$&*|#OVWazk*pdemmUj|=&QRyr4%v7}GnU?e^a|L*;5|{Jd8dFDhAQ2VQf~5|
zX-a(T_kOasRil{Tk(A6OcyvyCiH27dh~@03s#?xevbEaopl*`#`}bf2TQBI@FR9n;
z0s0(roK_tZFanD_WqJt}1&e8F-_@qUQKh1+v9XUrWrxXvvrHeZJeQhqg@>;L@Ky%L
z+A~l@OjhD+uSj@?)~^ujq3r{Wu3b?GdO1Y90=H4I3#EtGipcgHP?pcMGSe(bj{aEq
zsn{+KUWnc#?|$&!TIiH1n9_<g846CDSOIs$`elVVfp-1G?~FHGYUat%v}qGjL-&Ss
z$GM8btEFaP@ZyWuRZ~>xRfTunLa76<vHGAmWWhi0_-}MjPG+mC2$M>m?0x5iB_YSw
z0L1K;WaB)?bjuoN{P`t-T~oy|UR~PwyBW*{l{`y=1z~t&T$OdhqHNH}k8RwIxQZ>H
zFV_|6mlUidi|CJc0x)Nm=^$#>wDBXonkX-efVf4jx`%pAj-cZA5pzBEzu+fDVUSIl
z^4_rkyL<q=je+Z2E3Wt@42d`D^GH{H5-<1$;UjG1N{|n~`pfcxdP=um41n01WYltS
zC_1~Y6;4ei$-Ea-Bu56zX>Stzga_8Jy}62BSu`38Zxkr(pzW3SQ6dCmJ#j*E5j%Q=
zh>UNQWk{cKX^tb7&(f4o9ocLIN~vHAnql)dBKxF)Si!%Dj0#kV{D}#Tq})?!E$O&|
zfTGRq*6bx?F;sW@SOa$Zm+RN9xdk>ZFqYYjMAvsmPlU6x?}U5<sk`(~zHlvMyb3>+
zHTZyid>^q+S2fTqUg9Uau=1}$L`*u4_WPV;d@*tB0uC})8xsKf6{GUM@1O}mLG~F1
z$Xsnp5C>ziFGzvh3q~&z$qU6I>DzGVNSp%<fmYGVSHn-jji2S)NUR5hVk%cYcpIgp
z3`4H@%-hN_I1j4WE14z_@mtPv8n`x&Opyn1P9f07-Gm}>X1Lf$Hwd?^-U)>zQASNL
zwqrMh2hyZDLkuj&Ii>3`B?ZNT;u4Hm5`=OK^8*731$dZ-yY5#+Pty!R1pLB(Js$#C
z4g9!H->bZm7dT?L24RP!YOTL_0OFmcCZQ1&EKj!j7Efz(qtV)%Z6s>|84x$jptxei
zO3}Kd*a|zi{YDfIN-45n0-<Q}X9gLWenKIs*gJ(qLB!vksSVpjhw3Cv4bb8YVmVux
zCo=ITSB!hRjoT*0B?fzR{LD@?!|HNy<ayKO7vx#iSPRKUSrfX#U`s5KuP1(CEDv|X
zO#SX10D{QdB@*vCPl*vdM`{J9v&?9$V)^ihi8)sX?JTaxnhZ;Z%2>-q=uk|q9!+_)
zTN7Mg<^IFu#%y|=*K$TKE6O);5Z#G)yH}mLxrW_^3@4f8#)Xr$1ZQB-lNXk}t%>Hr
zb^B04g1IQh+x+yk^BU1KjE9aQTj}B}lig^0^+e}WpLus;5%9l>*x>&;_Eg*c+Y289
z1q;A4g%g`8npA8ep^2GO7&qvKr!t9E5Qz^PMaW!ou(pO<Axqv$RXzrzgmw?ux(;Xe
ze&)!xLZa)s<$OVpLV=?--%#ONdE$66eU@H70UD<ivnkQ`H`pZbI*_OFxfJwi>pCfk
zTBhoG`FjW$CKeQY4_`4<w&-&d+)<QKBPP(#xwm6~mET-zwlVGZ{dbH9?X(9=bgg3Y
zBK=Z!9?z5)0oM9C4;XAjne4|H#tdebX+%9XmeJkePNSE>tQ;<cCGcj)ZSPOe`v!9u
zLL7x?*^vy11w$C)$|t9eDTY*JBSMVdrLLS+R|pg9a@fG|YcBSdb1_evMVe#^Rg9=G
z`OcpNVwZeDG%Y8tdkwcMAeN-?8;4bm1@a6OsS^d)1pbLSkFdoCvvJM=2WWl{TUn1&
z&<w~KL45)%J0?XL%187@xzsMawCnHP<z)%nGVpIk*tkN-tb?sbhThZGYf(etW<p;a
z3dlddk}Q@ri#mYHx4-Xip2zU&orlD<z8}FLnL801iTW+ONWv-HKU<}^o<-G&!9e+(
zuhWzXkEH?0=SH-G4ZC;0AgZ&i1<9N#UO6KwB=JQW$&3v(Y~c<Axrj>9eTs{^g+I2$
z7#N!2@4j@+_-1I!rw?iqn^X9dG86F#O>9K}6oxxn6J%-qm?uK4XQ7^=2?}l3m~B?^
zBJDeP7@^M#!B;8UYflbCbjBWRBq)&p#DqSNv8&_1LrE2@2&Xb|KXI<~S2FGgje7an
zTNmDtwA4$DJ}bwJR<I%qZG=%+=E>QxV3eqnuajsXB@oTWN##QT5o|SC3cp+}GI={4
zkTwvBk8XpRj>J<DRmdSK(1)xw<!eSZ$lntz-+#D)BwZ~4;lmaI@z^U?>?e64kv}WE
z{a{2f($O+xUXT`eC{W=<$HyF0c3-v*1+_QWt*}AL{3{z>UlLwhoh!_FrkZt-%BQSS
z`Y1){4_0udQ*Bx-LeZEHZa&@qpl+?FO_ZY>^9tvmqg4s$@95{6CFuHCVI$X01Jp7Y
zDk-!9i6kmK)|l3nNN>mknn-tEY&QuVNosas^sX*Eg*$rw{Y>;yd<+p(1*n=rBx?pU
z)TIMJFz(&58%x52M(T1g(8F8v?<Is%49N&@jQ!%=cZ;O5wQ|}Q;@tj2|MSPzHzVG@
zi0%QHltO<#;$EV155cFsV)}hgOKebLb+yUFZnnNRiY-7)rEc-Ym_AYDF$#kYirWow
zY!j8r;V;gkdxLDf#3|X2f?v2rR7x0O$r?D$BG}&`byQIbbEOgg!IlSi=VD}(q&6xY
zEMbYETCv2#G}W}2;J4DQadN=xKang99;R9r=d(z#jvN4r5#fkz31^ru=1#PqvR&pQ
z{dxhzZMi6}y<~5oUzdu~u8gDkxmG(0mTPD4(BbK8cX^hg6c~~a3j?IGQoki3y^MUR
zLg`ajXlqY3iR}HE5es|m&hvT#0XVZXLHmK#Ok9yBMpsZR!0$mey~rs9mc1dNcIX(7
zrHK1&dulv|U2|vANpt9*6)FSl1#{&^?YXcdjsZxpes3m-<UC2L#fAB3D-|k<JZ<s4
z7}V^)$iLT!N3EXHo*0Yf7ZbDIli-G3ehfCa?l$m*aZJPGIv4jaZJ{{U+J|3pL6>o1
ziIKsE`+=nNT=iH(t<MKaR&L0xUzwARU-iKsaGS<NyQ@s-<?gZZPUuYIPr<G!l)aj}
zkn`ZYqznK3jH{=9Un?xo+~u(nJKSKW<_T_}AKgaK&s=A{pQ$Mzg+Vmx1sHoy`u#fa
zv=7qnC|dNHXDo>K&lVJmjI>+udswg_rW~pw71S3~)lUnlP9y<a^o^*rLmS!(0tVj^
zS}Wo8!$p(599z-B0feSPF9qS=W65TM@crLdxDZOWPlLzlyCRM`^@wF5Hq7Bk%q;2{
zvmm~9-a$XRJS2`q73?1Oe4)sS>;Y4P!lSzI2QS_GRm_#)eU@XI%mxbVrYte6jk47K
zKcx6;H+lI_{jio;pfSPf9<Qf-3WEo}^K|8Qy3?WRH$_~@%M<X8R;%7Nb}ytmz>pp4
znlK>Hk6>-bPsx!8_U@=3%3Zh>IJ!7KkFnK+#Y&c=$TigDZN8ImqM~%j3!nH^6fZ&`
z_5#&5f$bn;ix{p#(#MiGb5rT#b9d)qZl6L_4R_o%MbLI#Z@+{XJEAc`xvYio{0x$|
zg0M-M_Uig3G`&!cWhI}G=@8Zo5163}T0??W`HuEDO<Qqk57<O&f;Ua$JejMgakyAg
z{pv|V>UloSr{B-UgBH>M;)cu-cJ6tYv{M0ChiT53FQHiV?m){=Ig~wtcv{FOW!<a*
zmYRPe{8O>>36$I!O{6DS1@?z8&b~iz+{4`;nU{F!P@0IRrRk#jEB}O&g)AUDrf5ID
zj<%|h{XO6P>+wHLH-R7(iF!J{na_=dP!5<s+lhVMJ|0!{^aWgALR-@xCs9IU5n}R$
zFqlc!D9WSY#2r2yN%QoL=)$7oMiqc4;j#{?R0c<_7{)A5%z!)u4U(fDePJVGSF;a4
z-~;*pJOBL#m0hc6<^n7jH-d=kypz|Yk;Kc9+S@*WgtuMmFbr@&9|*)m<Wi@~{HXm&
zHI*r<8&Rj;)NPqs8jMu5Ny3;kGI~dJ?VNehW?|A+QCc($iy29ic?~wW5t*@OOouon
zDU-Ly+6!L_x}g6aAmFQim@0JGg(YHQaAXt(!HB?e-X5&r&bKKq!Am<U$mhq_K|dS<
zHbz$J2qH%xTq2}s1~h^N{L%-;q>DhnL8E`c={msZS00Q(h4kRE-R8$_mR308T<J+v
z1epx?UfV&skLwl3Avu|W0jPj{`aSW3)hwF1d8dq`Oh>v5v~NrAmDv63Ul@;CTxb?x
ziOM}EGkXxubOKdXM&WRtZqAW%RADr=S?XVsS`DRpBSrRuSFh=5mMK%P;h%QVk{^q#
zVt<$Sw;S3n0k)#D+7r;~48>?J`ChjxO1=YAzlW$;BC54Aj_f0jw1VLh)Ml6g=rPto
zd2PUq;vxzvKQ64GD#w+0LDU1^uY#v;oVvVpz@xuBDs}>YEiAOL##;R9bkThLGWIo=
zuk^7T6T2?%cPiy!kH!99)0o3@JOGNVxHvlCpEb^5c%l&*(-2y`u%XJTad=-_))k!E
z3%0L&nLf7gre)EDcnVok&M99`=z)3S%CtOmx}gDBCB{{wWYAn5*C~26Ms`HcpY~HY
zGAA;m>gw31_2J9H>gDhF$09|8mi`42AllKhwFGB3&>b6d%u`jl0*le@w=Cp+Fio@i
zFoniV?}^J!7CO~?Zj;TWuHo*Royz>)^7eJ`xfNy5$F3UlQD*IrGtb;m2%V_a`>77v
zer0;?L119?)qQ-GB2|NTAxf}SCx#;3s9K|@xp{h8P4c|OsN5g>?r(ANwwOtFaf7Qn
zF2z5k<9gj)h5b&>LX+&yC4zmAeu@tiA&;;e$mWhp^Y;h9otUbP1KI7w9KLh?pwaVp
za*B+e-|6o6C1hd{tf;O8K8HN2p%jg|dT8n-yUQh+bfgP(J0}1)0WM4St`V;5`6j}#
zPljM6dASrK&BtwuL924&#fR<062E`f22SfkiB_}#FDiqs+oi%g!WLkU$aoa>VDnyY
zo2MviWIOwM5Dp4Q7%1At(yM_1GSg=OsFFWP>^h!gZV2aB%oE|}2PM?e2Ft|Ln=?Bn
zGWj|T>j4^sB}j6tmhqX#`xzsk>Lf#lKkT8CKp9O!%2^tbi0nslZHW*O;VFv4XR944
z9N8;}kpB2xW0LF*wi0^L+hCkclnSk}n`xzBINB{EP>Yd=xfie*#~^6aJb<&2c#~g&
z7ETO}5o9FvQ9Of4^8Ui0i}p^}ZoYml14-HkSC5f>tu2fMJ6MLsh41rbY$)fJt|7`+
z>l*Ehf{JNbK{dHeW~r~uF9#GWsTe`Y^2}F>K(@<tde4Or9a2G2;@D$<`Z>Q@(mft7
z*=WbL%%w_5Yg#V16h4&I5qxrLC#N$sMU*%nfL6%fgDQ2->GkI`T&TWfx}^xv^;^=K
z9)=H2;E<MEJL}t7hE77tS~7i75}u>Qi0da)HDU@>w@1>UQ1gi0Z%R#yAl9XzNO%9$
z=Bm1Um;I1-0XA2uxVHXlkpJfZC63p!Yg{A*E;uvm+TG9K_=ffgRq5Z2kG+7AD??-l
z5i*OqiRD`zk5&_xIYMrUq-W+v)u7pHS`%wQ_nySDJW73*5$UY)`Cdow-vmaDUuAAg
z)Lery0m19^Vrp_+RI)T|_R$$GE=wvAdQ$Uf$dBrry28f3Q$IfT!PHc{S{mC#lAAjj
zi!XC0xenNG<19URh!eLY-PeuD%epm@HdQW6=GbqlX<?49K*EASypW5j>~YwKrPx_z
z=saqpCHMJ20ha$(umNhjPhL+Sj$1EEyncH?F&M_x^8q1Bnz}HsbpLmBzviS)+iQ%V
zc3osKHECc5YqllBNw1SNek*<pwfZZ2pKr+7;QCl&UWT3mWf|G4Z{j7}uD>nZrD(W!
zq4^xvpiZ_96IAm-t209chVn=_9%*zdF2Y2WVo*ZlgY-Lrg6I4|NCJkKY9%6c^f&ly
z1!?ACek~^GJwFpAUfM@{##Ktl%^<4t@pr(8VWObTBz{sMMqEf%w=%cKCEt;IuAl5G
zW#WgA2gI{>$9z50)}Cj6_~|07upXFoEsH7g^K%f?J+kqa8QPk{Xi{TdCX4$d&IG^t
zkOv~r7E8#-gQUi21-iZk{rYR+BWFJ!#|{l^;vmH7bifIvUycZ#BKioKW=2%*m&5@(
zhm&xO>5vcN@&QG+tT3QY-wT_sn(|bHUxn_7G*jKcF8cwOWffx#SoG^)USZUq!6-A<
zG+RhStKxTsT{I7l2tPbsKisdIz{ru_ZO9)FNAiD|0&W|1;rI3w!OU$9dmo(%?20M;
zKXw<MWSeaYP|e&C;>rjKLTdJ6D3cK6Ss=ovL=2k@bc262ij#w{G%Y$_TSs}b|4luy
z{!X>2l&<*xyvL{v62Y(*))vt+vv8WP7YSoclaIn2A<Uyd$6;lm7lZkwA~nkEC79Rv
zNpx-Es`_l_wt+CGJ8ow#Zf)i_azReFTMC{&Mz!{EU5&gKr`e9HQ`0EZg&${fl~>BP
z$F@oO9coJ`2HYwufi(NmQ^(o2>VBiHJgo%a9?-V$y(2d{!LuxN%J>vLE`ibgeiB3$
z>$#cs;ph{TM!YLm3($;E0Y%9OP@|(E+a5+vkAJHb`pQtxqB8#_OcWS+CL}qRzr$}T
z?6i33qtJ?%$4n<he2Bp%Rs3pR+Ibb#!=G7D2#i(##{FHN&imD!C}(=}zQ<M;+P*b+
zHNCBS{G^H`SW$y3h;V=c%Kdmx;Dh#R%v<i3zm!Xw+t(@WT)WV(=9Z!lgiMG97nN=k
zr^6r6o)B4l@&R4ZQ+u9b)i$LB_#*h6ulz@ikXMo8klubyFa^Wzw8nL)o|cHNJ6D?d
z>@9Ec-K?!8d_OKPdm-;E?ByuO2y(KTatvyY?=Z3T`U2?Zdx-dY_jJkf!#5J~_WOjI
zM?oQ->==P0L6G_m!o6;)%5gWV>X8_(RzcHq!#Y4XEdA1KZe9rjjI^jqi9e*=Z-^(Q
zlb8mCkmeV)odu;+6_?06P??ga*##K`X@Y5f<L;4)AhkIMk;+KJ9$LL$r84U~ow;uQ
z$9_fnd)I2qpIKs~_+Cw~LeHxk7A!*PB88M5%8<z$49d(zruQ>m3OxkRdvK#@s}+Sp
zd=LeJhjcuF7R>Kl1bI))KfSR6T8`0LTD1*w$D9mk+{u1QdRuCP;yE(S_+|0sPa(pW
zR#OLHLkRYc1_DSUYt&HYP|O?2oSa>N1eY-Rb~!C49l}w}pd!TO8id8^E<~sJ@LQ%f
zaxoxMai6PjO6E~xq0a(8wn3N0(*+c`<k8Lv?W;;haNFMg4btELl89=c|0oFm*6Usc
znOB4sdNhh^A&nbD$Lv6a3nQ;KdQco(agKd1Ea=%fp7PkII4Vc3G^O9`!fj8YjfORO
z@#?z3W^p)KgqDhcS6HctFCCGB7^kCJTun6b?)?J8L)nKzmmYFukBEdw`YYkm`qKW_
zjAe&)xBK#}8dUBJu+COYHsKdbFrtP)G;*V2KfLjQsLTk-(wTMl{I$+U-IaU+$**)k
zMBu_l5k+=K-CFC+7J)%kpU?A?!d7K-Y=5f`2p;Qi&xKd=sw4?~@I3l=s9(5(H9z`T
ztoq(pTDy|&B%E`nf5juK)Xh+{r=a%C)eE^Dnt7-lx1K;>pe3;@%;R4Dh*jqeE`skb
zsaL?*EG0hsE;eJt&>@?*(>AHKiP%*lC;^0`15>sQIin`fo4boH98xLM<2o7!LhcrP
ztCLo)>0FJuXiJ%jG|##@Xl$AfQXJ*_XHNIx+1GU2vz_^qAUhp^^5HgrEv-Jd%jl73
z`IB4wlsVDRlA}F$0?A~`oM8CI)Dn66k%c2>3^2WMMfg75IccoRTcMhhz1<v4tu>om
zXg1@8FJ+6EhJgz2f$rFM*7yN_^8ESN*18dxOJ*#cr28$h2pm8|=78~gOawP-uHbH(
zGxlc$=cRAqg4Ud&MIuztQ*j<iiQ$aCC_7MGf8;z58O?E3E?q{el5YBEH}g$h4Rl#B
z4F_QSlzc;h((^Ts+MstY<<hJf15{4Z_t=ylz5C8{!AJbb*n{xteJeMlY4h*6p<@z}
zec5b>w$YosJIYSaXmb;$!W|nxqzo3Iy&w`tc`5&<siTT)HT1dJjx@M4kDuleGCFkW
zN%9jkn|~IWtT*H?!9Ys?a%LGTZ%P>%ga+pfd8q<nQn^=;{e`xo^(cz>5j68i*uv=$
zv?NB41Iw1uc64S+(Z8?|l{y@3uod+ho+B!Vz2o+UkGMxlVTO7*dZbnFHxO|p-@a-|
z8RYBeb0=w+`sW&4JvqI7cKj-j*>_FXS4tPmt}_BHQai`x0b8S?n53+ZBrxWyrYp6}
zE;*X>enF6N?j9QxvJbuu0G$LhVg|fk0Me|})>g&H3T@+8zArUM1k3>WN{ga7QyOG>
zRwTG$?2{yc6b}-a18WA0PwG1AL?JHvh5Qq|jX+|K!!LzmcP+$!x6l`OuH?b{H65`J
z4e_MZ2{&u0ws!Q*i<VrVLJ|=OTxsOW3U1$J%$-&L@ketli09#_*}y~Evk%XgWs85@
zVC)Cf$geepGVgA-Z2b_lsvS(@DMFkorK1Jb!9)sOoB{J!oFY+8*NM-&;p+SB9giv^
ze>?&ZM8^~KL%j5(PQl=M<50>e1r)F`8HBl`^lw6@az;kAC_<43JM041gr|{qBWU=A
z%yl}3e;Ga<J~lLwgM%Yng_cA!)gG>OTkf(V!z+}-o~Dk~*@9}i_b-D^MS3&*g<^*v
z;Bzf?#8rj>p*SEXK{%n5^yB9>OvgVRGk*o30Qlo>Mwm7LtW<C2-JxGlD<pJ}&Tc=E
zd&B0ZoR7F7$AKjQhzl0T>d07<yUtHBCbSXZRRPc9)UViKr{|=89&_xGT(2YS`nV<f
zB?<_;^4LUF*astff(reUQHT?U=AWvRN+P@lDp`@SKvkE_*@-pJo;qsKm2D?(okux-
zC`AjYGmqpPBD~TFO<sL2@n^c+5r2&hU_|ZP*VSh#ZLo<bm7f8&AjdhswlDeXh(_V;
zRsdH(;74cmLFBc{aqq2!(|12FF#ej|E5-4c?YQV~%a^#)J_?T+vw~KT3dRpv^Dr7)
zXlU@Vyi!<e>;%i=W2bK$h@1Ng=AYbgIC`8sNMwp<Ho1I>!xc46i%QS-Fe=o~MnXV9
zjD0Q$(U<!_4M-BMbo52!Kz7g<!2<5|mL+6S8kr359J1nDVUPbh;^6md&$ru(EGH>!
z>a%zZ#<*1##^0~Fd0%E`?(#dzHWNHyg$AF-Tje)@_qp((d2shBv-o%Yw(A(M&VwnI
z=k&ndesNk3G@H%5>$^xsXDme@!zU{hkFd1jzrC_!7F4Y_G{{ng{M@gb22UIH$RML`
z1*cjn?k?R7u)@o(I0*_hHY_nBq)_mc>8NOkV~OysRGuZ)eTI8~41CO~j*GWqovQ7K
zYYqP=7$px6kkvYl5sI7RaK2_+LWv0fDJK<nxJ-wHDd#5}06x|*g~{?H2v`bJ8Y|{P
z+yd&JVv_svS^>mgpV{mgzbZZzzhyF^#Ki7L4xZ#NBlYNi>t0j4sYZj+Ll!NMT;fYo
zB)vPzzBhPZ>uN#?Bh#D-?s=@OICYo*&At&7*m2JL5D)8F7=6cclT=<u$gaq{7D+nW
zn!i*&vY=RM%v$8+MwrtgRJK6V_~NEv<oT$qP<C2XXFHP-n?K`v_MO>)OwbOA^))I0
z&<H$;KtGc6hvj6E359FtQAfcuXGCg~SUF4sWYU$V#&8<jV<MCv_Azd-+^*{)?w#c*
z@zzqWyHz8<CEOwUv)Fb`Q8K@O^GN_ciJ;f+vpLW&vyU8Wl-Whtx3a1wh^Y%(%>J^L
z|CTlX)vW-<k_zMZcrx3+O0p%YfzG-F{)Ib(j(CmZU`!RhN?x7ga>jok#0P0zRsyp`
zP2lun)$(JtLcr7|9Kuagz<O5wvNAuvF^k;NATQCQkuCyrJZZfqB~c7hm$OBmU&2*J
zdHm(sYn}#L<6FBCC8j=jDm{^L%jtQt85{JMB-hQQtnpaO(4Zy7Cp?rCmSpqsM@L^9
z_N|^vk1mUf&sv&(IjA4)Ny^5m)S)@F@`AqOD$mZ?(8xlH0KC4*-S3X-P~qZ=UIU89
zHKn&hy?KFus=COlQ||mr0Z}MIh)~F?8QI5w#-!8dg(X);=%(dI^S3f?n{)h6n^Hi6
zrC{YI?qYL3T+tfa>F*crjKT`T1F6^HY{98BD0sls(h8KuXaQsQ`y96wV-QY2!)@53
z*Jh&Pnr~Mk1o*w%+oc7yZrz)A$t~w`{NZW%W}ZiE<=Cy$dRub<9Z?nID8<FY51VaZ
zwa2$ssKn6{`FUzKKe%4F0lEH?HCByjXBOYsaFy*QAgmC}N?<rZ20)eIrdMACQR*b+
zjOcf9Kk9C!n}vW-Xdt!=wQVGULOu!CnF4qDFT?<+V#!YyYoP0Q6oYPk^Nd%{a7^Vy
zNN?stXwBU{Et%sujDkaa`tKjxfA+!g|Mhz1ny9^4aQnq<jM3oaM4NPzZV&DGU+N}P
zgQr4ntvKV2&oS$bySp%{p_qYvwYi^~>Dk4JI&#K8r1Xzh-<dfphP-tczkhAi!!Y0w
z#prwTQiIAAPIx+k3Z75e)!%w_ol0hQ_{d6gryG^8;D3?-aT<}>Mi#q_pr$YJ{MM>L
z4Pui-+R_($1j#Z9X?O$1xwD<JQy(A`g*LTwObkx&aD%#bW+g_Zd=BO!+|5=xO~hhw
z;VJ&pd<DYmF_6({>-h3D8QEvW_r-!H2;&aiUxl{wa76OYr_MAgMNLlG#zZuC(-LmN
ztC@Y8!|1<dh3t03;dgk;{*X1vXSo!ly!%RF@HXjy#v;m%ab1xti{vS~fTu1SN_Jkf
zWj@ftE^FJxYB6=Kkss7&&<-#6BBH$sxhS>G;pJ~+rQzQtF7+=vZV+7ZyX3{Y!(&*J
zMsA^(liGfr8Gyr|k`C#{1~1!UB<f(*^K*08W9vF`m)#C1@EJcW7%Lar9<=%ZlV=nY
zYA|#TjrN<*&-0`T{9=fsYM0a!?~|ghSr?GPPB1a7ZZH&o$R$Hg?~U5)KD_Sq_cj5~
z0aOw23T5E?g-8QP6i31^qXtr_VM2j!h^eBm5N(%k{@{Ku%}=)$eou70j?8b0U_<fi
zWCXPIpglAC?IH)>DW2E#7Y`GguN5pu+ODeSuA?dYur=e)XN3P#;DedN1@J!{99gS%
zfrp-yf9C!V4V6{gJzwqTAiMR>O9OQbiz$b_0L5#k%0KyLx43+;vBb`*iUZWnHka$B
z<=~sy>lO($!$2jFiC>TDR_E;6Zqt>(g4b~~aO+z^WKsr)e0&-)`l{!?V+;=@3QsGK
zXitJ8I`whrYtrXfG-}SSp)>AnI3elBlH}iyn4HS>JBP~<`vn!ArkRRPW{37^J=F*a
z?!)wINVO~}0LNR5Du8wapt&i?t3ltrza(5GC`1q30<V5+?V#7@bsis!->Cjk>gvxk
zS*6OCgaKTtqmiAaCKgsM5^N|-irn&AIy``P{j2#$$Fu)i2xbV)aysfodp)0YL1WEg
zda_*iE+c}M#5)P6i2vozwDq~o2BiW01o{isETMXtN~sDY1NXx)`WrM0uc>hNKeCVV
z!^lpnnx4IN(;w%Awc8*(C27y5hrsO1gqe_FSKno~-Fn;YleiRWhk7kuf_?0VI|>hq
zj2v6-(X?n7psg>}V?u<L!?j~zfGJ&w@ax1ce_f#8C+gknr&ZkQV$r6MzvTV4fl9AN
zxV#F$K}v2Zeo5`%o?qi`kD2%nfH+=hF<ix^Sl0q~`ONb73~>U(4v_k>ZLn24w^sWh
z!>F9y-{)(?H$Rkl=Y~Upwcb-PYfBtWo=itUWoa(}=!Zw>=XG5ixi3h4Isf8k4CmwY
zR~&`%)c1F%Wgf+R=eV#w#8@p!+5;<aSGeOA>sZTu>Ni!kte1-J*~I;Ix`%u@?qe9T
zjfmOT^EAOj*6J?i#nmN?)1z&=-)s3;w*-J-X7Teepqgac^5f8_$ZgVSkQ;{?ZWpEB
z^r+n-?aGr;L+v^-<C_$f|MNhz)!?kuY`6j0o-75TI$w<j+jeQ;_`pIPMvdV-{3QS8
zJZ_hPovU*-17f9d4RL>Y4>@>f29kx3Sk_PoSx7NR10Pg{yIPDKMULq3u<f+G5V;p(
z0ja|9eO20m5u4*k0M(|;VZn1T<|>QPDI9q^q2Z#9qJat#QSNq!vF+GaLh~<T>k%ML
zKT1Va2Fd}WiF6rP&~LhLV4YhS0DDttz3t4WyJ9w7n>hBn$`7Z43AVMNIOHwAoKlkX
z;<w2D>lcKPzN>%%OaMQ8kT$SIt!lpJTs4Aa?X+IVGo#b{IbMbSUW5rP?l0_pM?i{e
zx%pIO5uZeU?p@mW?`{iPHM?wN%%!S?nrPE6PPy8$1sM58Qj{o4_&4YyU2ZD7IReLJ
z5`%zD-BtF1d>>z8G#Aj3pDdF1qI_H@Q2Reb$aJi8DB99P)jckt-*Z3D7UP;TU}Oqa
z_U)~XThu`BuNil7|KQO)uCksW?7iq4e627FbAES*G<x`Q!=QkbA`9r<O^58Zq&@xc
z`YK6Hq6W^LS8MlY?luzd;6<xhG8nC#B!}yC4#$#?ORU%nG${DHKW$zje&Q2F@E*QY
zO@K75S~Jy5XsUr7`3z$iwiC4tAiFU<6#C9Cj0hHa+{6Xa<Je>mDzlP*@%w_0#rf0^
zO^?~|u7wCfI^V5?>KXSl^l!JaoryU%Sz27q^W_ftPtth~G9(MDhz&X)f|@9&TJ)Kt
zny=S;Ct}LiVN_}>sh6Uu;%<|=i`WC6?-K`kPiq!8dQvHZT!8-&Cz393-2}5opF(zc
z0leohBu3$1KCFIwC5|C|joCOa4j~-hm0j1F7h0BTO-pWEiI|-ydl&a-##aY3f--o=
zEOvBVM>_XvlfNbN$Q)shH*Zx9FUWRQ%`&Rn4@IRur4P{=3B%P#=ZD40CxW_e$vjlV
zIh4~nOCPoL7G_<~3%q>rj}7#}9J<b$k@*n}8@cE?Q)&u<k9u^d%^q5pGiQ&@53vHP
z^VPZIYYV7PMqub?(y>?GENqU~F47JD3#f+5P?Lq-z$h(k7(I%*IqmQ|PWgR5iDWuo
zG8l7C2WTL(j#O>W!tl)GUPuj<_{ltEYi@v4!7?60;3a<FAIGYhOlUgqELOC$&S$O3
z5Yf4f#K~`mJPtgCk%YoT{J5Nt4(r<<d&z?IAHh&of0B)PX0@{W3F{w^`W^Tj_Uv8J
zc}EFzgm9y(ntpoopZK!Qb(NTNy3AuOzUM5N-`tb_rJmdcKVUKu40z_^!gD%Z;zdXo
zY(etd{5`ZoFlr6|7G<3kSL93`WQ(rh3EhqJste$dgOXgg@<H92^kkmxxmRVbKh6ut
ze8R3VICih+TfDx|-*0_jSO_<*d}pcnAWU&ZwQ*O92sz-3K&Gd&W8_p7l%qybq>6kb
zl0m)PPAB%d(uMNR77dGORG%2?v6>7aAzQ$<bYDUUW$#_cFjIf}xffM7YIG~NP48Ua
zahz`ctXxYqi7mpx27UIdp@kvEvZUzD32sMbfw6?lL-u&w;TvO|@EZCPVg^6N+)`~i
zYWfY!7c4n>sHGCDf-6dcAhJKr(PU%L9={Rhpg`O-KLp2tlGq{I&WM`TgVgQjWRg*k
z*m!@)YUH%!-jvBZ;(KmB7B-KCP^<ID4+smBvOT!2cgVQ;I~<8RyUG0{QY3LD0e5Q!
zIP(c3{c(Bvv9e2CODkQ#z3Dc2QbN-4@ZbU&cyDQBvfCT;q>ZuG7`D_s>q4xcjOT99
z)iN~`y7=TYr2^$ZeP4J@zmJUag;`z5hVq^xh5!v&GI!+K6er!5O#>Sl)kLSOzI>QY
za^@%nA$`G?9bHrc{p=E&`5=VHtX+8PHIwKxU#OUu*YcRIbc-<X>oeYGc_77_BkJWJ
zW2hvq)fdaYrf2Ej?1j~(_&=`CYpLegPXd1!3&{KOutDT>A%8;}3?uLBYLu^^xqU`)
z!hKT)A!BfW^L1}x7B$rAKjke&X{k4mnX#1+-JUfrWP1T%e(1AoJDo2N)RG^!CYD9>
vT;KYNS9)I0XB}Oe|2KpC|H%da1v_7!g9Xnn81bLGA0R8KBvB`39P<AFR}s-y

literal 0
HcmV?d00001

diff --git a/Source/Core/Windows/LinedefEditForm.Designer.cs b/Source/Core/Windows/LinedefEditForm.Designer.cs
index 4f8163d83..aa9ef86e9 100644
--- a/Source/Core/Windows/LinedefEditForm.Designer.cs
+++ b/Source/Core/Windows/LinedefEditForm.Designer.cs
@@ -407,7 +407,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.frontlow.Size = new System.Drawing.Size(83, 107);
 			this.frontlow.TabIndex = 6;
 			this.frontlow.TextureName = "";
-			this.frontlow.UsePreviews = true;
 			this.frontlow.OnValueChanged += new System.EventHandler(this.frontlow_OnValueChanged);
 			// 
 			// frontmid
@@ -419,7 +418,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.frontmid.Size = new System.Drawing.Size(83, 107);
 			this.frontmid.TabIndex = 5;
 			this.frontmid.TextureName = "";
-			this.frontmid.UsePreviews = true;
 			this.frontmid.OnValueChanged += new System.EventHandler(this.frontmid_OnValueChanged);
 			// 
 			// fronthigh
@@ -431,7 +429,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.fronthigh.Size = new System.Drawing.Size(83, 107);
 			this.fronthigh.TabIndex = 4;
 			this.fronthigh.TextureName = "";
-			this.fronthigh.UsePreviews = true;
 			this.fronthigh.OnValueChanged += new System.EventHandler(this.fronthigh_OnValueChanged);
 			// 
 			// frontTextureOffset
@@ -506,7 +503,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.backlow.Size = new System.Drawing.Size(83, 107);
 			this.backlow.TabIndex = 6;
 			this.backlow.TextureName = "";
-			this.backlow.UsePreviews = true;
 			this.backlow.OnValueChanged += new System.EventHandler(this.backlow_OnValueChanged);
 			// 
 			// backmid
@@ -518,7 +514,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.backmid.Size = new System.Drawing.Size(83, 107);
 			this.backmid.TabIndex = 5;
 			this.backmid.TextureName = "";
-			this.backmid.UsePreviews = true;
 			this.backmid.OnValueChanged += new System.EventHandler(this.backmid_OnValueChanged);
 			// 
 			// backhigh
@@ -530,7 +525,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.backhigh.Size = new System.Drawing.Size(83, 107);
 			this.backhigh.TabIndex = 4;
 			this.backhigh.TextureName = "";
-			this.backhigh.UsePreviews = true;
 			this.backhigh.OnValueChanged += new System.EventHandler(this.backhigh_OnValueChanged);
 			// 
 			// backTextureOffset
diff --git a/Source/Core/Windows/LinedefEditFormUDMF.Designer.cs b/Source/Core/Windows/LinedefEditFormUDMF.Designer.cs
index d731d5630..2c38ab769 100644
--- a/Source/Core/Windows/LinedefEditFormUDMF.Designer.cs
+++ b/Source/Core/Windows/LinedefEditFormUDMF.Designer.cs
@@ -857,7 +857,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.frontlow.Size = new System.Drawing.Size(220, 189);
 			this.frontlow.TabIndex = 6;
 			this.frontlow.TextureName = "";
-			this.frontlow.UsePreviews = false;
 			this.frontlow.OnValueChanged += new System.EventHandler(this.frontlow_OnValueChanged);
 			// 
 			// frontmid
@@ -869,7 +868,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.frontmid.Size = new System.Drawing.Size(220, 189);
 			this.frontmid.TabIndex = 5;
 			this.frontmid.TextureName = "";
-			this.frontmid.UsePreviews = false;
 			this.frontmid.OnValueChanged += new System.EventHandler(this.frontmid_OnValueChanged);
 			// 
 			// fronthigh
@@ -881,7 +879,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.fronthigh.Size = new System.Drawing.Size(220, 189);
 			this.fronthigh.TabIndex = 4;
 			this.fronthigh.TextureName = "";
-			this.fronthigh.UsePreviews = false;
 			this.fronthigh.OnValueChanged += new System.EventHandler(this.fronthigh_OnValueChanged);
 			// 
 			// tabback
@@ -1285,7 +1282,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.backlow.Size = new System.Drawing.Size(220, 189);
 			this.backlow.TabIndex = 6;
 			this.backlow.TextureName = "";
-			this.backlow.UsePreviews = false;
 			this.backlow.OnValueChanged += new System.EventHandler(this.backlow_OnValueChanged);
 			// 
 			// backmid
@@ -1297,7 +1293,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.backmid.Size = new System.Drawing.Size(220, 189);
 			this.backmid.TabIndex = 5;
 			this.backmid.TextureName = "";
-			this.backmid.UsePreviews = false;
 			this.backmid.OnValueChanged += new System.EventHandler(this.backmid_OnValueChanged);
 			// 
 			// backhigh
@@ -1309,7 +1304,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.backhigh.Size = new System.Drawing.Size(220, 189);
 			this.backhigh.TabIndex = 4;
 			this.backhigh.TextureName = "";
-			this.backhigh.UsePreviews = false;
 			this.backhigh.OnValueChanged += new System.EventHandler(this.backhigh_OnValueChanged);
 			// 
 			// tabcomment
diff --git a/Source/Core/Windows/PreferencesForm.Designer.cs b/Source/Core/Windows/PreferencesForm.Designer.cs
index 5d5dce0aa..b0188d677 100644
--- a/Source/Core/Windows/PreferencesForm.Designer.cs
+++ b/Source/Core/Windows/PreferencesForm.Designer.cs
@@ -38,9 +38,7 @@ namespace CodeImp.DoomBuilder.Windows
 			System.Windows.Forms.Label label27;
 			System.Windows.Forms.Label label29;
 			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PreferencesForm));
-			this.capitalizetexturenames = new System.Windows.Forms.CheckBox();
 			this.blackbrowsers = new System.Windows.Forms.CheckBox();
-			this.keepfilterfocused = new System.Windows.Forms.CheckBox();
 			this.checkforupdates = new System.Windows.Forms.CheckBox();
 			this.cbStoreEditTab = new System.Windows.Forms.CheckBox();
 			this.locatetexturegroup = new System.Windows.Forms.CheckBox();
@@ -59,13 +57,11 @@ namespace CodeImp.DoomBuilder.Windows
 			this.autoscrollspeed = new System.Windows.Forms.TrackBar();
 			this.autoscrollspeedlabel = new System.Windows.Forms.Label();
 			this.label15 = new System.Windows.Forms.Label();
-			this.previewsize = new System.Windows.Forms.TrackBar();
-			this.previewsizelabel = new System.Windows.Forms.Label();
-			this.label12 = new System.Windows.Forms.Label();
 			this.label14 = new System.Windows.Forms.Label();
 			this.defaultviewmode = new System.Windows.Forms.ComboBox();
 			this.keyusedlabel = new System.Windows.Forms.Label();
 			this.colorsgroup1 = new System.Windows.Forms.GroupBox();
+			this.colorguidelines = new CodeImp.DoomBuilder.Controls.ColorControl();
 			this.color3dFloors = new CodeImp.DoomBuilder.Controls.ColorControl();
 			this.colorInfo = new CodeImp.DoomBuilder.Controls.ColorControl();
 			this.colorMD3 = new CodeImp.DoomBuilder.Controls.ColorControl();
@@ -213,7 +209,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.pasteoptions = new CodeImp.DoomBuilder.Controls.PasteOptionsControl();
 			this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
 			this.browseScreenshotsFolderDialog = new System.Windows.Forms.FolderBrowserDialog();
-			this.colorguidelines = new CodeImp.DoomBuilder.Controls.ColorControl();
 			label7 = new System.Windows.Forms.Label();
 			label5 = new System.Windows.Forms.Label();
 			groupBox1 = new System.Windows.Forms.GroupBox();
@@ -226,7 +221,6 @@ namespace CodeImp.DoomBuilder.Windows
 			((System.ComponentModel.ISupportInitialize)(this.vertexScale)).BeginInit();
 			((System.ComponentModel.ISupportInitialize)(this.zoomfactor)).BeginInit();
 			((System.ComponentModel.ISupportInitialize)(this.autoscrollspeed)).BeginInit();
-			((System.ComponentModel.ISupportInitialize)(this.previewsize)).BeginInit();
 			this.colorsgroup1.SuspendLayout();
 			((System.ComponentModel.ISupportInitialize)(this.doublesidedalpha)).BeginInit();
 			this.tabs.SuspendLayout();
@@ -281,9 +275,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			// groupBox1
 			// 
-			groupBox1.Controls.Add(this.capitalizetexturenames);
 			groupBox1.Controls.Add(this.blackbrowsers);
-			groupBox1.Controls.Add(this.keepfilterfocused);
 			groupBox1.Controls.Add(this.checkforupdates);
 			groupBox1.Controls.Add(this.cbStoreEditTab);
 			groupBox1.Controls.Add(this.locatetexturegroup);
@@ -302,9 +294,6 @@ namespace CodeImp.DoomBuilder.Windows
 			groupBox1.Controls.Add(this.autoscrollspeed);
 			groupBox1.Controls.Add(this.autoscrollspeedlabel);
 			groupBox1.Controls.Add(this.label15);
-			groupBox1.Controls.Add(this.previewsize);
-			groupBox1.Controls.Add(this.previewsizelabel);
-			groupBox1.Controls.Add(this.label12);
 			groupBox1.Controls.Add(this.label14);
 			groupBox1.Controls.Add(this.defaultviewmode);
 			groupBox1.Location = new System.Drawing.Point(8, 8);
@@ -314,44 +303,20 @@ namespace CodeImp.DoomBuilder.Windows
 			groupBox1.TabStop = false;
 			groupBox1.Text = " Options ";
 			// 
-			// capitalizetexturenames
-			// 
-			this.capitalizetexturenames.AutoSize = true;
-			this.capitalizetexturenames.Location = new System.Drawing.Point(16, 350);
-			this.capitalizetexturenames.Name = "capitalizetexturenames";
-			this.capitalizetexturenames.Size = new System.Drawing.Size(140, 17);
-			this.capitalizetexturenames.TabIndex = 11;
-			this.capitalizetexturenames.Text = "Capitalize texture names";
-			this.toolTip1.SetToolTip(this.capitalizetexturenames, "When enabled, texture names will be shown \r\nand saved as all caps\r\n(Doom Builder " +
-					"2 behaviour)");
-			this.capitalizetexturenames.UseVisualStyleBackColor = true;
-			// 
 			// blackbrowsers
 			// 
 			this.blackbrowsers.AutoSize = true;
-			this.blackbrowsers.Location = new System.Drawing.Point(16, 329);
+			this.blackbrowsers.Location = new System.Drawing.Point(16, 277);
 			this.blackbrowsers.Name = "blackbrowsers";
 			this.blackbrowsers.Size = new System.Drawing.Size(195, 17);
 			this.blackbrowsers.TabIndex = 10;
 			this.blackbrowsers.Text = "Black background in image browser";
 			this.blackbrowsers.UseVisualStyleBackColor = true;
 			// 
-			// keepfilterfocused
-			// 
-			this.keepfilterfocused.AutoSize = true;
-			this.keepfilterfocused.Location = new System.Drawing.Point(16, 308);
-			this.keepfilterfocused.Name = "keepfilterfocused";
-			this.keepfilterfocused.Size = new System.Drawing.Size(280, 17);
-			this.keepfilterfocused.TabIndex = 9;
-			this.keepfilterfocused.Text = "Keep Filter input focused when image browser is open";
-			this.toolTip1.SetToolTip(this.keepfilterfocused, "When enabled, all key presses in \r\nimage browsers will be redirected \r\nto the Fil" +
-					"ter textbox.");
-			this.keepfilterfocused.UseVisualStyleBackColor = true;
-			// 
 			// checkforupdates
 			// 
 			this.checkforupdates.AutoSize = true;
-			this.checkforupdates.Location = new System.Drawing.Point(16, 413);
+			this.checkforupdates.Location = new System.Drawing.Point(16, 346);
 			this.checkforupdates.Name = "checkforupdates";
 			this.checkforupdates.Size = new System.Drawing.Size(160, 17);
 			this.checkforupdates.TabIndex = 14;
@@ -361,7 +326,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// cbStoreEditTab
 			// 
 			this.cbStoreEditTab.AutoSize = true;
-			this.cbStoreEditTab.Location = new System.Drawing.Point(16, 392);
+			this.cbStoreEditTab.Location = new System.Drawing.Point(16, 323);
 			this.cbStoreEditTab.Name = "cbStoreEditTab";
 			this.cbStoreEditTab.Size = new System.Drawing.Size(203, 17);
 			this.cbStoreEditTab.TabIndex = 13;
@@ -371,7 +336,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// locatetexturegroup
 			// 
 			this.locatetexturegroup.AutoSize = true;
-			this.locatetexturegroup.Location = new System.Drawing.Point(16, 287);
+			this.locatetexturegroup.Location = new System.Drawing.Point(16, 254);
 			this.locatetexturegroup.Name = "locatetexturegroup";
 			this.locatetexturegroup.Size = new System.Drawing.Size(267, 17);
 			this.locatetexturegroup.TabIndex = 8;
@@ -384,7 +349,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			this.recentFiles.BackColor = System.Drawing.SystemColors.Window;
 			this.recentFiles.LargeChange = 1;
-			this.recentFiles.Location = new System.Drawing.Point(127, 193);
+			this.recentFiles.Location = new System.Drawing.Point(127, 156);
 			this.recentFiles.Maximum = 25;
 			this.recentFiles.Minimum = 8;
 			this.recentFiles.Name = "recentFiles";
@@ -397,7 +362,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// labelRecentFiles
 			// 
 			this.labelRecentFiles.AutoSize = true;
-			this.labelRecentFiles.Location = new System.Drawing.Point(249, 205);
+			this.labelRecentFiles.Location = new System.Drawing.Point(249, 168);
 			this.labelRecentFiles.Name = "labelRecentFiles";
 			this.labelRecentFiles.Size = new System.Drawing.Size(13, 13);
 			this.labelRecentFiles.TabIndex = 48;
@@ -406,7 +371,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// label25
 			// 
 			this.label25.AutoSize = true;
-			this.label25.Location = new System.Drawing.Point(31, 206);
+			this.label25.Location = new System.Drawing.Point(31, 169);
 			this.label25.Name = "label25";
 			this.label25.Size = new System.Drawing.Size(87, 13);
 			this.label25.TabIndex = 47;
@@ -416,7 +381,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// vertexScaleLabel
 			// 
 			this.vertexScaleLabel.AutoSize = true;
-			this.vertexScaleLabel.Location = new System.Drawing.Point(249, 168);
+			this.vertexScaleLabel.Location = new System.Drawing.Point(249, 131);
 			this.vertexScaleLabel.Name = "vertexScaleLabel";
 			this.vertexScaleLabel.Size = new System.Drawing.Size(74, 13);
 			this.vertexScaleLabel.TabIndex = 45;
@@ -425,7 +390,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// label22
 			// 
 			this.label22.AutoSize = true;
-			this.label22.Location = new System.Drawing.Point(26, 168);
+			this.label22.Location = new System.Drawing.Point(26, 131);
 			this.label22.Name = "label22";
 			this.label22.Size = new System.Drawing.Size(91, 13);
 			this.label22.TabIndex = 44;
@@ -436,7 +401,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			this.vertexScale.BackColor = System.Drawing.SystemColors.Window;
 			this.vertexScale.LargeChange = 1;
-			this.vertexScale.Location = new System.Drawing.Point(127, 156);
+			this.vertexScale.Location = new System.Drawing.Point(127, 119);
 			this.vertexScale.Minimum = 1;
 			this.vertexScale.Name = "vertexScale";
 			this.vertexScale.Size = new System.Drawing.Size(116, 45);
@@ -448,7 +413,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// cbSynchCameras
 			// 
 			this.cbSynchCameras.AutoSize = true;
-			this.cbSynchCameras.Location = new System.Drawing.Point(16, 371);
+			this.cbSynchCameras.Location = new System.Drawing.Point(16, 300);
 			this.cbSynchCameras.Name = "cbSynchCameras";
 			this.cbSynchCameras.Size = new System.Drawing.Size(294, 17);
 			this.cbSynchCameras.TabIndex = 12;
@@ -458,7 +423,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// showtexturesizes
 			// 
 			this.showtexturesizes.AutoSize = true;
-			this.showtexturesizes.Location = new System.Drawing.Point(16, 266);
+			this.showtexturesizes.Location = new System.Drawing.Point(16, 231);
 			this.showtexturesizes.Name = "showtexturesizes";
 			this.showtexturesizes.Size = new System.Drawing.Size(208, 17);
 			this.showtexturesizes.TabIndex = 7;
@@ -468,7 +433,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// scriptontop
 			// 
 			this.scriptontop.AutoSize = true;
-			this.scriptontop.Location = new System.Drawing.Point(16, 245);
+			this.scriptontop.Location = new System.Drawing.Point(16, 208);
 			this.scriptontop.Name = "scriptontop";
 			this.scriptontop.Size = new System.Drawing.Size(227, 17);
 			this.scriptontop.TabIndex = 6;
@@ -479,7 +444,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			this.zoomfactor.BackColor = System.Drawing.SystemColors.Window;
 			this.zoomfactor.LargeChange = 1;
-			this.zoomfactor.Location = new System.Drawing.Point(127, 119);
+			this.zoomfactor.Location = new System.Drawing.Point(127, 82);
 			this.zoomfactor.Minimum = 1;
 			this.zoomfactor.Name = "zoomfactor";
 			this.zoomfactor.Size = new System.Drawing.Size(116, 45);
@@ -491,7 +456,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// zoomfactorlabel
 			// 
 			this.zoomfactorlabel.AutoSize = true;
-			this.zoomfactorlabel.Location = new System.Drawing.Point(249, 131);
+			this.zoomfactorlabel.Location = new System.Drawing.Point(249, 94);
 			this.zoomfactorlabel.Name = "zoomfactorlabel";
 			this.zoomfactorlabel.Size = new System.Drawing.Size(27, 13);
 			this.zoomfactorlabel.TabIndex = 39;
@@ -500,7 +465,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// label19
 			// 
 			this.label19.AutoSize = true;
-			this.label19.Location = new System.Drawing.Point(52, 131);
+			this.label19.Location = new System.Drawing.Point(52, 94);
 			this.label19.Name = "label19";
 			this.label19.Size = new System.Drawing.Size(67, 13);
 			this.label19.TabIndex = 38;
@@ -510,7 +475,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			this.autoscrollspeed.BackColor = System.Drawing.SystemColors.Window;
 			this.autoscrollspeed.LargeChange = 1;
-			this.autoscrollspeed.Location = new System.Drawing.Point(127, 82);
+			this.autoscrollspeed.Location = new System.Drawing.Point(127, 45);
 			this.autoscrollspeed.Maximum = 5;
 			this.autoscrollspeed.Name = "autoscrollspeed";
 			this.autoscrollspeed.Size = new System.Drawing.Size(116, 45);
@@ -521,7 +486,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// autoscrollspeedlabel
 			// 
 			this.autoscrollspeedlabel.AutoSize = true;
-			this.autoscrollspeedlabel.Location = new System.Drawing.Point(249, 94);
+			this.autoscrollspeedlabel.Location = new System.Drawing.Point(249, 57);
 			this.autoscrollspeedlabel.Name = "autoscrollspeedlabel";
 			this.autoscrollspeedlabel.Size = new System.Drawing.Size(21, 13);
 			this.autoscrollspeedlabel.TabIndex = 36;
@@ -530,43 +495,12 @@ namespace CodeImp.DoomBuilder.Windows
 			// label15
 			// 
 			this.label15.AutoSize = true;
-			this.label15.Location = new System.Drawing.Point(26, 94);
+			this.label15.Location = new System.Drawing.Point(26, 57);
 			this.label15.Name = "label15";
 			this.label15.Size = new System.Drawing.Size(91, 13);
 			this.label15.TabIndex = 35;
 			this.label15.Text = "Auto-scroll speed:";
 			// 
-			// previewsize
-			// 
-			this.previewsize.BackColor = System.Drawing.SystemColors.Window;
-			this.previewsize.LargeChange = 1;
-			this.previewsize.Location = new System.Drawing.Point(127, 45);
-			this.previewsize.Maximum = 5;
-			this.previewsize.Name = "previewsize";
-			this.previewsize.Size = new System.Drawing.Size(116, 45);
-			this.previewsize.TabIndex = 1;
-			this.previewsize.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
-			this.previewsize.Value = 5;
-			this.previewsize.ValueChanged += new System.EventHandler(this.previewsize_ValueChanged);
-			// 
-			// previewsizelabel
-			// 
-			this.previewsizelabel.AutoSize = true;
-			this.previewsizelabel.Location = new System.Drawing.Point(249, 57);
-			this.previewsizelabel.Name = "previewsizelabel";
-			this.previewsizelabel.Size = new System.Drawing.Size(54, 13);
-			this.previewsizelabel.TabIndex = 33;
-			this.previewsizelabel.Text = "128 x 128";
-			// 
-			// label12
-			// 
-			this.label12.AutoSize = true;
-			this.label12.Location = new System.Drawing.Point(17, 57);
-			this.label12.Name = "label12";
-			this.label12.Size = new System.Drawing.Size(100, 13);
-			this.label12.TabIndex = 32;
-			this.label12.Text = "Preview image size:";
-			// 
 			// label14
 			// 
 			this.label14.AutoSize = true;
@@ -666,6 +600,17 @@ namespace CodeImp.DoomBuilder.Windows
 			this.colorsgroup1.Text = " Colors ";
 			this.colorsgroup1.Visible = false;
 			// 
+			// colorguidelines
+			// 
+			this.colorguidelines.BackColor = System.Drawing.Color.Transparent;
+			this.colorguidelines.Label = "Guidelines:";
+			this.colorguidelines.Location = new System.Drawing.Point(15, 307);
+			this.colorguidelines.MaximumSize = new System.Drawing.Size(10000, 23);
+			this.colorguidelines.MinimumSize = new System.Drawing.Size(100, 23);
+			this.colorguidelines.Name = "colorguidelines";
+			this.colorguidelines.Size = new System.Drawing.Size(168, 23);
+			this.colorguidelines.TabIndex = 11;
+			// 
 			// color3dFloors
 			// 
 			this.color3dFloors.BackColor = System.Drawing.Color.Transparent;
@@ -1978,6 +1923,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// scripttabwidth
 			// 
 			this.scripttabwidth.AllowDecimal = false;
+			this.scripttabwidth.AllowExpressions = false;
 			this.scripttabwidth.AllowNegative = false;
 			this.scripttabwidth.AllowRelative = false;
 			this.scripttabwidth.ButtonStep = 2;
@@ -2405,17 +2351,6 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			this.browseScreenshotsFolderDialog.Description = "Select a Folder to Save Screenshots Into";
 			// 
-			// colorguidelines
-			// 
-			this.colorguidelines.BackColor = System.Drawing.Color.Transparent;
-			this.colorguidelines.Label = "Guidelines:";
-			this.colorguidelines.Location = new System.Drawing.Point(15, 307);
-			this.colorguidelines.MaximumSize = new System.Drawing.Size(10000, 23);
-			this.colorguidelines.MinimumSize = new System.Drawing.Size(100, 23);
-			this.colorguidelines.Name = "colorguidelines";
-			this.colorguidelines.Size = new System.Drawing.Size(168, 23);
-			this.colorguidelines.TabIndex = 11;
-			// 
 			// PreferencesForm
 			// 
 			this.AcceptButton = this.apply;
@@ -2443,7 +2378,6 @@ namespace CodeImp.DoomBuilder.Windows
 			((System.ComponentModel.ISupportInitialize)(this.vertexScale)).EndInit();
 			((System.ComponentModel.ISupportInitialize)(this.zoomfactor)).EndInit();
 			((System.ComponentModel.ISupportInitialize)(this.autoscrollspeed)).EndInit();
-			((System.ComponentModel.ISupportInitialize)(this.previewsize)).EndInit();
 			this.colorsgroup1.ResumeLayout(false);
 			((System.ComponentModel.ISupportInitialize)(this.doublesidedalpha)).EndInit();
 			this.tabs.ResumeLayout(false);
@@ -2544,9 +2478,6 @@ namespace CodeImp.DoomBuilder.Windows
 		private System.Windows.Forms.CheckBox qualitydisplay;
 		private System.Windows.Forms.CheckBox visualbilinear;
 		private System.Windows.Forms.CheckBox classicbilinear;
-		private System.Windows.Forms.TrackBar previewsize;
-		private System.Windows.Forms.Label previewsizelabel;
-		private System.Windows.Forms.Label label12;
 		private System.Windows.Forms.TrackBar autoscrollspeed;
 		private System.Windows.Forms.Label autoscrollspeedlabel;
 		private System.Windows.Forms.Label label15;
@@ -2647,7 +2578,6 @@ namespace CodeImp.DoomBuilder.Windows
 		private System.Windows.Forms.ComboBox scriptcolorpresets;
 		private System.Windows.Forms.Label label23;
 		private CodeImp.DoomBuilder.Controls.ColorControl colorproperties;
-		private System.Windows.Forms.CheckBox keepfilterfocused;
 		private System.Windows.Forms.Label labelantialiasing;
 		private System.Windows.Forms.TrackBar antialiasing;
 		private System.Windows.Forms.Label labelanisotropicfiltering;
@@ -2661,7 +2591,6 @@ namespace CodeImp.DoomBuilder.Windows
 		private System.Windows.Forms.Label activethingsalphalabel;
 		private System.Windows.Forms.Label label31;
 		private System.Windows.Forms.TrackBar activethingsalpha;
-		private System.Windows.Forms.CheckBox capitalizetexturenames;
 		private System.Windows.Forms.CheckBox blackbrowsers;
 		private System.Windows.Forms.GroupBox groupBox11;
 		private System.Windows.Forms.Label label28;
diff --git a/Source/Core/Windows/PreferencesForm.cs b/Source/Core/Windows/PreferencesForm.cs
index 194b9d5d9..8da4ec2f8 100644
--- a/Source/Core/Windows/PreferencesForm.cs
+++ b/Source/Core/Windows/PreferencesForm.cs
@@ -73,7 +73,6 @@ namespace CodeImp.DoomBuilder.Windows
 			vertexScale3D.Value = General.Clamp((int)(General.Settings.GZVertexScale3D * 10), vertexScale3D.Minimum, vertexScale3D.Maximum); //mxd
 			viewdistance.Value = General.Clamp((int)(General.Settings.ViewDistance / 200.0f), viewdistance.Minimum, viewdistance.Maximum);
 			invertyaxis.Checked = General.Settings.InvertYAxis;
-			previewsize.Value = General.Clamp(General.Settings.PreviewImageSize, previewsize.Minimum, previewsize.Maximum);
 			autoscrollspeed.Value = General.Clamp(General.Settings.AutoScrollSpeed, autoscrollspeed.Minimum, autoscrollspeed.Maximum);
 			zoomfactor.Value = General.Clamp(General.Settings.ZoomFactor, zoomfactor.Minimum, zoomfactor.Maximum);
 			animatevisualselection.Checked = General.Settings.AnimateVisualSelection;
@@ -92,7 +91,6 @@ namespace CodeImp.DoomBuilder.Windows
 
 			//mxd
 			locatetexturegroup.Checked = General.Settings.LocateTextureGroup;
-			keepfilterfocused.Checked = General.Settings.KeepTextureFilterFocused;
 			cbStoreEditTab.Checked = General.Settings.StoreSelectedEditTab;
 			checkforupdates.Checked = General.Settings.CheckForUpdates;
 			toolbar_gzdoom.Checked = General.Settings.GZToolbarGZDoom;
@@ -253,7 +251,6 @@ namespace CodeImp.DoomBuilder.Windows
 			scriptcolorpresets.SelectedIndex = 0;
 
 			blackbrowsers.Checked = General.Settings.BlackBrowsers;
-			capitalizetexturenames.Checked = General.Settings.CapitalizeTextureNames; //mxd
 			classicbilinear.Checked = General.Settings.ClassicBilinear;
 			visualbilinear.Checked = General.Settings.VisualBilinear;
 			qualitydisplay.Checked = General.Settings.QualityDisplay;
@@ -291,7 +288,6 @@ namespace CodeImp.DoomBuilder.Windows
 			
 			// Check if we need to reload the resources
 			reloadresources |= (General.Settings.ImageBrightness != imagebrightness.Value);
-			reloadresources |= (General.Settings.PreviewImageSize != previewsize.Value);
 
 			// Apply interface
 			General.Settings.ImageBrightness = imagebrightness.Value;
@@ -306,7 +302,6 @@ namespace CodeImp.DoomBuilder.Windows
 			General.Settings.GZVertexScale3D = vertexScale3D.Value * 0.1f; //mxd
 			General.Settings.ViewDistance = viewdistance.Value * 200.0f;
 			General.Settings.InvertYAxis = invertyaxis.Checked;
-			General.Settings.PreviewImageSize = previewsize.Value;
 			General.Settings.AutoScrollSpeed = autoscrollspeed.Value;
 			General.Settings.ZoomFactor = zoomfactor.Value;
 			General.Settings.AnimateVisualSelection = animatevisualselection.Checked;
@@ -326,7 +321,6 @@ namespace CodeImp.DoomBuilder.Windows
 			General.Settings.StoreSelectedEditTab = cbStoreEditTab.Checked; //mxd
 			General.Settings.CheckForUpdates = checkforupdates.Checked; //mxd
 			General.Settings.LocateTextureGroup = locatetexturegroup.Checked; //mxd
-			General.Settings.KeepTextureFilterFocused = keepfilterfocused.Checked; //mxd
 			General.Settings.MaxRecentFiles = recentFiles.Value; //mxd
 			General.Settings.ScreenshotsPath = screenshotsfolderpath.Text.Trim(); //mxd
 
@@ -400,7 +394,6 @@ namespace CodeImp.DoomBuilder.Windows
 
 			General.Colors.CreateAssistColors();
 			General.Settings.BlackBrowsers = blackbrowsers.Checked;
-			General.Settings.CapitalizeTextureNames = capitalizetexturenames.Checked; //mxd
 			General.Settings.ClassicBilinear = classicbilinear.Checked;
 			General.Settings.VisualBilinear = visualbilinear.Checked;
 			General.Settings.QualityDisplay = qualitydisplay.Checked;
@@ -478,12 +471,6 @@ namespace CodeImp.DoomBuilder.Windows
 		#endregion
 
 		#region ================== Interface Panel
-
-		private void previewsize_ValueChanged(object sender, EventArgs e)
-		{
-			int size = PreviewManager.PREVIEW_SIZES[previewsize.Value];
-			previewsizelabel.Text = size + " x " + size;
-		}
 		
 		private void fieldofview_ValueChanged(object sender, EventArgs e)
 		{
diff --git a/Source/Core/Windows/ScriptFindReplaceForm.Designer.cs b/Source/Core/Windows/ScriptFindReplaceForm.Designer.cs
index e1984e2ab..0ca9a4619 100644
--- a/Source/Core/Windows/ScriptFindReplaceForm.Designer.cs
+++ b/Source/Core/Windows/ScriptFindReplaceForm.Designer.cs
@@ -345,6 +345,7 @@ namespace CodeImp.DoomBuilder.Windows
 			this.ShowIcon = false;
 			this.ShowInTaskbar = false;
 			this.Text = "Find and Replace";
+			this.Shown += new System.EventHandler(this.ScriptFindReplaceForm_Shown);
 			this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ScriptFindReplaceForm_FormClosing);
 			this.tabs.ResumeLayout(false);
 			this.tabfind.ResumeLayout(false);
diff --git a/Source/Core/Windows/ScriptFindReplaceForm.cs b/Source/Core/Windows/ScriptFindReplaceForm.cs
index 108af1809..cb9c540c6 100644
--- a/Source/Core/Windows/ScriptFindReplaceForm.cs
+++ b/Source/Core/Windows/ScriptFindReplaceForm.cs
@@ -363,6 +363,7 @@ namespace CodeImp.DoomBuilder.Windows
 					findbox.Items.AddRange(items);
 				}
 				findbox.SelectAll();
+				findbox.Focus();
 
 				findinbox.SelectedIndex = replaceinbox.SelectedIndex;
 
@@ -380,6 +381,7 @@ namespace CodeImp.DoomBuilder.Windows
 					replacefindbox.Items.AddRange(items);
 				}
 				replacefindbox.SelectAll();
+				replacefindbox.Focus();
 
 				replaceinbox.SelectedIndex = findinbox.SelectedIndex;
 
@@ -392,6 +394,14 @@ namespace CodeImp.DoomBuilder.Windows
 			}
 		}
 
+		//mxd. Focus text input
+		private void ScriptFindReplaceForm_Shown(object sender, EventArgs e)
+		{
+			if(tabs.SelectedTab == tabfind) findbox.Focus();
+			else if(tabs.SelectedTab == tabreplace) replacefindbox.Focus();
+			else throw new NotImplementedException("Unsupported tab type");
+		}
+
 		#endregion
 	}
 }
\ No newline at end of file
diff --git a/Source/Core/Windows/SectorEditForm.Designer.cs b/Source/Core/Windows/SectorEditForm.Designer.cs
index 7f3c7d736..e8095ff9c 100644
--- a/Source/Core/Windows/SectorEditForm.Designer.cs
+++ b/Source/Core/Windows/SectorEditForm.Designer.cs
@@ -53,8 +53,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.ceilingtex = new CodeImp.DoomBuilder.Controls.FlatSelectorControl();
 			this.cancel = new System.Windows.Forms.Button();
 			this.apply = new System.Windows.Forms.Button();
-			this.flatSelectorControl2 = new CodeImp.DoomBuilder.Controls.FlatSelectorControl();
-			this.flatSelectorControl1 = new CodeImp.DoomBuilder.Controls.FlatSelectorControl();
 			this.panel1 = new System.Windows.Forms.Panel();
 			this.tooltip = new System.Windows.Forms.ToolTip(this.components);
 			label1 = new System.Windows.Forms.Label();
@@ -311,7 +309,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.floortex.Size = new System.Drawing.Size(114, 138);
 			this.floortex.TabIndex = 2;
 			this.floortex.TextureName = "";
-			this.floortex.UsePreviews = true;
 			this.floortex.OnValueChanged += new System.EventHandler(this.floortex_OnValueChanged);
 			// 
 			// floorheight
@@ -341,7 +338,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.ceilingtex.Size = new System.Drawing.Size(114, 138);
 			this.ceilingtex.TabIndex = 3;
 			this.ceilingtex.TextureName = "";
-			this.ceilingtex.UsePreviews = true;
 			this.ceilingtex.OnValueChanged += new System.EventHandler(this.ceilingtex_OnValueChanged);
 			// 
 			// cancel
@@ -367,26 +363,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.apply.UseVisualStyleBackColor = true;
 			this.apply.Click += new System.EventHandler(this.apply_Click);
 			// 
-			// flatSelectorControl2
-			// 
-			this.flatSelectorControl2.Location = new System.Drawing.Point(271, 37);
-			this.flatSelectorControl2.MultipleTextures = false;
-			this.flatSelectorControl2.Name = "flatSelectorControl2";
-			this.flatSelectorControl2.Size = new System.Drawing.Size(83, 105);
-			this.flatSelectorControl2.TabIndex = 13;
-			this.flatSelectorControl2.TextureName = "";
-			this.flatSelectorControl2.UsePreviews = true;
-			// 
-			// flatSelectorControl1
-			// 
-			this.flatSelectorControl1.Location = new System.Drawing.Point(363, 37);
-			this.flatSelectorControl1.MultipleTextures = false;
-			this.flatSelectorControl1.Name = "flatSelectorControl1";
-			this.flatSelectorControl1.Size = new System.Drawing.Size(83, 105);
-			this.flatSelectorControl1.TabIndex = 12;
-			this.flatSelectorControl1.TextureName = "";
-			this.flatSelectorControl1.UsePreviews = true;
-			// 
 			// panel1
 			// 
 			this.panel1.BackColor = System.Drawing.SystemColors.Window;
@@ -439,8 +415,6 @@ namespace CodeImp.DoomBuilder.Windows
 		private System.Windows.Forms.Button apply;
 		private CodeImp.DoomBuilder.Controls.FlatSelectorControl floortex;
 		private CodeImp.DoomBuilder.Controls.FlatSelectorControl ceilingtex;
-		private CodeImp.DoomBuilder.Controls.FlatSelectorControl flatSelectorControl2;
-		private CodeImp.DoomBuilder.Controls.FlatSelectorControl flatSelectorControl1;
 		private System.Windows.Forms.Label sectorheight;
 		private CodeImp.DoomBuilder.Controls.ActionSelectorControl effect;
 		private System.Windows.Forms.Button browseeffect;
diff --git a/Source/Core/Windows/SectorEditForm.resx b/Source/Core/Windows/SectorEditForm.resx
index e0a9f8806..7f637e047 100644
--- a/Source/Core/Windows/SectorEditForm.resx
+++ b/Source/Core/Windows/SectorEditForm.resx
@@ -159,10 +159,4 @@
   <metadata name="label4.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>False</value>
   </metadata>
-  <metadata name="flatSelectorControl2.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>True</value>
-  </metadata>
-  <metadata name="flatSelectorControl1.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>True</value>
-  </metadata>
 </root>
\ No newline at end of file
diff --git a/Source/Core/Windows/SectorEditFormUDMF.Designer.cs b/Source/Core/Windows/SectorEditFormUDMF.Designer.cs
index c78069a26..6cbcdc577 100644
--- a/Source/Core/Windows/SectorEditFormUDMF.Designer.cs
+++ b/Source/Core/Windows/SectorEditFormUDMF.Designer.cs
@@ -988,7 +988,6 @@
 			this.floortex.Size = new System.Drawing.Size(190, 204);
 			this.floortex.TabIndex = 11;
 			this.floortex.TextureName = "";
-			this.floortex.UsePreviews = false;
 			this.floortex.OnValueChanged += new System.EventHandler(this.floortex_OnValueChanged);
 			// 
 			// groupBox1
@@ -1270,7 +1269,6 @@
 			this.ceilingtex.Size = new System.Drawing.Size(190, 204);
 			this.ceilingtex.TabIndex = 11;
 			this.ceilingtex.TextureName = "";
-			this.ceilingtex.UsePreviews = false;
 			this.ceilingtex.OnValueChanged += new System.EventHandler(this.ceilingtex_OnValueChanged);
 			// 
 			// tabslopes
diff --git a/Source/Core/Windows/TextureBrowserForm.Designer.cs b/Source/Core/Windows/TextureBrowserForm.Designer.cs
index 1276b4d35..d076ed4df 100644
--- a/Source/Core/Windows/TextureBrowserForm.Designer.cs
+++ b/Source/Core/Windows/TextureBrowserForm.Designer.cs
@@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			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(683, 411);
+			this.cancel.Location = new System.Drawing.Point(682, 413);
 			this.cancel.Name = "cancel";
 			this.cancel.Size = new System.Drawing.Size(98, 25);
 			this.cancel.TabIndex = 3;
@@ -60,9 +60,10 @@ namespace CodeImp.DoomBuilder.Windows
 			// 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(581, 411);
+			this.apply.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
+			this.apply.Location = new System.Drawing.Point(682, 381);
 			this.apply.Name = "apply";
-			this.apply.Size = new System.Drawing.Size(98, 25);
+			this.apply.Size = new System.Drawing.Size(98, 30);
 			this.apply.TabIndex = 2;
 			this.apply.TabStop = false;
 			this.apply.Text = "OK";
@@ -97,7 +98,7 @@ namespace CodeImp.DoomBuilder.Windows
 			this.tvTextureSets.SelectedImageIndex = 0;
 			this.tvTextureSets.SelectionBackColor = System.Drawing.SystemColors.Highlight;
 			this.tvTextureSets.SelectionMode = CodeImp.DoomBuilder.Controls.TreeViewSelectionMode.SingleSelect;
-			this.tvTextureSets.Size = new System.Drawing.Size(198, 402);
+			this.tvTextureSets.Size = new System.Drawing.Size(198, 374);
 			this.tvTextureSets.TabIndex = 4;
 			this.tvTextureSets.TabStop = false;
 			this.tvTextureSets.KeyUp += new System.Windows.Forms.KeyEventHandler(this.tvTextureSets_KeyUp);
@@ -105,7 +106,6 @@ namespace CodeImp.DoomBuilder.Windows
 			// 
 			// browser
 			// 
-			this.browser.BrowseFlats = false;
 			this.browser.Dock = System.Windows.Forms.DockStyle.Fill;
 			this.browser.HideInputBox = false;
 			this.browser.Location = new System.Drawing.Point(0, 0);
diff --git a/Source/Core/Windows/TextureBrowserForm.cs b/Source/Core/Windows/TextureBrowserForm.cs
index d5667897b..be36e1282 100644
--- a/Source/Core/Windows/TextureBrowserForm.cs
+++ b/Source/Core/Windows/TextureBrowserForm.cs
@@ -17,7 +17,7 @@
 #region ================== Namespaces
 
 using System;
-using System.Drawing;
+using System.Collections.Generic;
 using System.Windows.Forms;
 using CodeImp.DoomBuilder.Controls;
 using CodeImp.DoomBuilder.IO;
@@ -31,13 +31,19 @@ namespace CodeImp.DoomBuilder.Windows
 {
 	internal partial class TextureBrowserForm : DelayedForm
 	{
+		//mxd. Structs
+		private struct TreeNodeData
+		{
+			public IFilledTextureSet Set;
+			public string FolderName;
+		}
+		
 		// Variables
 		private string selectedname;
-		private readonly ListViewGroup usedgroup;
-		private readonly ListViewGroup availgroup;
+		private readonly string usedgroup;
+		private readonly string availgroup;
 		private TreeNode selectedset; //mxd
 		private long selecttextureonfill; //mxd. Was string, which wasn't reliable whem dealing with long texture names
-		private readonly bool usedgroupcollapsed; //mxd
 		private readonly bool browseflats; //mxd
 		
 		// Properties
@@ -63,11 +69,14 @@ namespace CodeImp.DoomBuilder.Windows
 			string imagetype = (browseflats ? "flats" : "textures");
 			this.Text = "Browse " + imagetype;
 
+			// Make groups
+			usedgroup = "Used " + imagetype + ":";
+			availgroup = "Available " + imagetype + ":";
+			browser.AddGroup(availgroup);
+			browser.AddGroup(usedgroup);
+
 			// Setup texture browser
-			ImageBrowserControl.ShowTexturesFromSubDirectories = General.Settings.ReadSetting("windows." + configname + ".showtexturesfromsubdirs", true);
-			ImageBrowserControl.UseLongTextureNames = General.Map.Options.UseLongTextureNames;
-			browser.BrowseFlats = browseflats;
-			browser.ApplySettings();
+			browser.ApplySettings("windows." + configname, browseflats);
 			
 			// Update the used textures
 			General.Map.Data.UpdateUsedTextures();
@@ -77,14 +86,6 @@ namespace CodeImp.DoomBuilder.Windows
 			//mxd. Texture longname to select when list is filled
 			selecttextureonfill = longname;
 
-			// Make groups
-			usedgroup = browser.AddGroup("Used " + imagetype + ":");
-			availgroup = browser.AddGroup("Available " + imagetype + ":");
-
-			//mxd. Make "Used" group collapsible
-			usedgroupcollapsed = General.Settings.ReadSetting("windows." + configname + ".usedgroupcollapsed", false);
-			browser.SetGroupCollapsed(usedgroup, usedgroupcollapsed);
-
 			//mxd. Fill texture sets list with normal texture sets
 			foreach(IFilledTextureSet ts in General.Map.Data.TextureSets) 
 			{
@@ -94,7 +95,7 @@ namespace CodeImp.DoomBuilder.Windows
 
 				item = tvTextureSets.Nodes.Add(ts.Name + " [" + count + "]");
 				item.Name = ts.Name;
-				item.Tag = ts;
+				item.Tag = new TreeNodeData { Set = ts, FolderName = ts.Name };
 				item.ImageIndex = 0;
 			}
 
@@ -105,9 +106,9 @@ namespace CodeImp.DoomBuilder.Windows
 				if((count == 0 && !General.Map.Config.MixTexturesFlats) || (ts.Flats.Count == 0 && ts.Textures.Count == 0))
 					continue;
 
-				item = tvTextureSets.Nodes.Add(ts.Name + " [" + count + "]");
+				item = tvTextureSets.Nodes.Add(ts.Name);
 				item.Name = ts.Name;
-				item.Tag = ts;
+				item.Tag = new TreeNodeData { Set = ts, FolderName = ts.Name };
 				item.ImageIndex = 2 + ts.Location.type;
 				item.SelectedImageIndex = item.ImageIndex;
 
@@ -119,7 +120,7 @@ namespace CodeImp.DoomBuilder.Windows
 			count = (browseflats ? General.Map.Data.AllTextureSet.Flats.Count : General.Map.Data.AllTextureSet.Textures.Count);
 			item = tvTextureSets.Nodes.Add(General.Map.Data.AllTextureSet.Name + " [" + count + "]");
 			item.Name = General.Map.Data.AllTextureSet.Name;
-			item.Tag = General.Map.Data.AllTextureSet;
+			item.Tag = new TreeNodeData { Set = General.Map.Data.AllTextureSet, FolderName = General.Map.Data.AllTextureSet.Name };
 			item.ImageIndex = 1;
 			item.SelectedImageIndex = item.ImageIndex;
 
@@ -142,7 +143,7 @@ namespace CodeImp.DoomBuilder.Windows
 
 				if(match != null)
 				{
-					IFilledTextureSet set = (match.Tag as IFilledTextureSet);
+					IFilledTextureSet set = ((TreeNodeData)match.Tag).Set;
 					foreach(ImageData img in (browseflats ? set.Flats : set.Textures))
 					{
 						if(img.LongName == longname)
@@ -176,7 +177,7 @@ namespace CodeImp.DoomBuilder.Windows
 				selectedset.EnsureVisible();
 			}
 
-			tvTextureSets.EndUpdate();//mxd
+			tvTextureSets.EndUpdate(); //mxd
 
 			//mxd. Set splitter position and state (doesn't work when layout is suspended)
 			if(General.Settings.ReadSetting("windows." + configname + ".splittercollapsed", false))
@@ -199,7 +200,13 @@ namespace CodeImp.DoomBuilder.Windows
 		//mxd
 		private static int SortImageData(ImageData img1, ImageData img2) 
 		{
-			return String.Compare(img1.FilePathName, img2.FilePathName, StringComparison.Ordinal);
+			return String.Compare(img1.Name, img2.Name, StringComparison.OrdinalIgnoreCase);
+		}
+
+		//mxd
+		private static int SortTreeNodes(TreeNode n1, TreeNode n2)
+		{
+			return String.Compare(n1.Text, n2.Text, StringComparison.OrdinalIgnoreCase);
 		}
 
 		//mxd
@@ -213,7 +220,7 @@ namespace CodeImp.DoomBuilder.Windows
 			}
 
 			//then - in current node
-			IFilledTextureSet set = (node.Tag as IFilledTextureSet);
+			IFilledTextureSet set = ((TreeNodeData)node.Tag).Set;
 
 			foreach(ImageData img in (browseflats ? set.Flats : set.Textures))
 				if(img.LongName == longname) return node;
@@ -235,9 +242,10 @@ namespace CodeImp.DoomBuilder.Windows
 		}
 
 		//mxd
-		private void CreateNodes(TreeNode root) 
+		private void CreateNodes(TreeNode root)
 		{
-			ResourceTextureSet set = root.Tag as ResourceTextureSet;
+			TreeNodeData rootdata = (TreeNodeData)root.Tag;
+			ResourceTextureSet set = rootdata.Set as ResourceTextureSet;
 			if(set == null) 
 			{
 				General.ErrorLogger.Add(ErrorType.Error, "Resource " + root.Name + " doesn't have TextureSet!");
@@ -260,14 +268,19 @@ namespace CodeImp.DoomBuilder.Windows
 			}
 			Array.Sort(images, SortImageData);
 
+			List<ImageData> rootimages = new List<ImageData>();
 			foreach(ImageData image in images) 
 			{
 				string[] parts = image.VirtualName.Split(separator, StringSplitOptions.RemoveEmptyEntries);
 				TreeNode curNode = root;
 
-				if(parts.Length == 1) continue;
-				int localindex = (parts[0] == "[TEXTURES]" ? 8 : imageIndex);
+				if(parts.Length == 1)
+				{
+					rootimages.Add(image);
+					continue;
+				}
 
+				int localindex = ((parts[0] == "[TEXTURES]" || image is TEXTURESImage) ? 8 : imageIndex);
 				string category = set.Name;
 				for(int i = 0; i < parts.Length - 1; i++) 
 				{
@@ -281,77 +294,94 @@ namespace CodeImp.DoomBuilder.Windows
 					else //create a new one
 					{
 						TreeNode n = new TreeNode(parts[i]) { Name = category, ImageIndex = localindex, SelectedImageIndex = localindex };
-
 						curNode.Nodes.Add(n);
 						curNode = n;
-
-						ResourceTextureSet ts = new ResourceTextureSet(category, set.Location);
-						ts.Level = i + 1;
-						curNode.Tag = ts;
+						curNode.Tag = new TreeNodeData { Set = new ResourceTextureSet(category, set.Location), FolderName = parts[i] };
 					}
 
-					//add to current and parent nodes
+					// Add to current node
 					if(i == parts.Length - 2) 
 					{
-						TreeNode cn = curNode;
-						while(cn != root) 
-						{
-							ResourceTextureSet curTs = cn.Tag as ResourceTextureSet;
-							if(image.IsFlat)
-								curTs.AddFlat(image);
-							else
-								curTs.AddTexture(image);
-							cn = cn.Parent;
-						}
+						ResourceTextureSet curTs = ((TreeNodeData)curNode.Tag).Set as ResourceTextureSet;
+						if(image.IsFlat)
+							curTs.AddFlat(image);
+						else
+							curTs.AddTexture(image);
 					}
 				}
 			}
 
+			// Shift the tree up when only single child node was added
 			if(root.Nodes.Count == 1 && root.Nodes[0].Nodes.Count > 0) 
 			{
 				TreeNode[] children = new TreeNode[root.Nodes[0].Nodes.Count];
 				root.Nodes[0].Nodes.CopyTo(children, 0);
 				root.Nodes.Clear();
 				root.Nodes.AddRange(children);
-				((ResourceTextureSet)root.Tag).Level++;
 			}
 
+			// Sort immediate child nodes...
+			TreeNode[] rootnodes = new TreeNode[root.Nodes.Count];
+			root.Nodes.CopyTo(rootnodes, 0);
+			Array.Sort(rootnodes, SortTreeNodes);
+			root.Nodes.Clear();
+			root.Nodes.AddRange(rootnodes);
+
+			// Re-add root images
+			ResourceTextureSet rootset = new ResourceTextureSet(set.Name, set.Location);
+			if(browseflats)
+			{
+				foreach(ImageData data in rootimages) rootset.AddFlat(data);
+			}
+			else
+			{
+				foreach(ImageData data in rootimages) rootset.AddTexture(data);
+			}
+
+			// Store root data
+			rootdata.Set = rootset;
+			root.Tag = rootdata;
+
+			// Set root images count
+			if(rootimages.Count > 0) root.Text += " [" + rootimages.Count + "]";
+
+			// Add image count to node titles
 			foreach(TreeNode n in root.Nodes) SetItemsCount(n);
 		}
 
 		//mxd
 		private void SetItemsCount(TreeNode node) 
 		{
-			ResourceTextureSet ts = node.Tag as ResourceTextureSet;
-			if(ts == null) throw new Exception("Expected IFilledTextureSet, but got null...");
+			ResourceTextureSet ts = ((TreeNodeData)node.Tag).Set as ResourceTextureSet;
+			if(ts == null) throw new Exception("Expected ResourceTextureSet, but got null...");
 			
 			if(node.Parent != null && General.Map.Config.MixTexturesFlats)
 			{
 				ts.MixTexturesAndFlats();
-				node.Text += " [" + ts.Textures.Count + "]";
+				if(ts.Textures.Count > 0) node.Text += " [" + ts.Textures.Count + "]";
 			} 
 			else
 			{
-				node.Text += " [" + (browseflats ? ts.Flats.Count : ts.Textures.Count) + "]";
+				int texcount = (browseflats ? ts.Flats.Count : ts.Textures.Count);
+				if(texcount > 0) node.Text += " [" + texcount + "]";
 			}
 
 			foreach(TreeNode child in node.Nodes) SetItemsCount(child);
 		}
 
 		// Selection changed
-		private void browser_SelectedItemChanged()
+		private void browser_SelectedItemChanged(ImageBrowserItem item)
 		{
-			apply.Enabled = (browser.SelectedItem != null);
+			apply.Enabled = (item != null && item.ItemType == ImageBrowserItemType.IMAGE);
 		}
 
 		// OK clicked
 		private void apply_Click(object sender, EventArgs e)
 		{
 			// Set selected name and close
-			if(browser.SelectedItem != null)
+			if(browser.SelectedItem != null && browser.SelectedItem.ItemType == ImageBrowserItemType.IMAGE)
 			{
-				ImageBrowserItem item = browser.SelectedItem as ImageBrowserItem;
-				selectedname = item.TextureName;
+				selectedname = browser.SelectedItem.TextureName;
 				DialogResult = DialogResult.OK;
 			}
 			else
@@ -384,92 +414,175 @@ namespace CodeImp.DoomBuilder.Windows
 			// Save window settings
 			General.Settings.WriteSetting("windows." + configname + ".splitterdistance", splitter.SplitPosition); //mxd
 			General.Settings.WriteSetting("windows." + configname + ".splittercollapsed", splitter.IsCollapsed); //mxd
-			General.Settings.WriteSetting("windows." + configname + ".usedgroupcollapsed", browser.IsGroupCollapsed(usedgroup)); //mxd
 
 			//mxd. Save last selected texture set
 			if(this.DialogResult == DialogResult.OK && tvTextureSets.SelectedNodes.Count > 0)
 				General.Settings.WriteSetting("windows." + configname + ".textureset", tvTextureSets.SelectedNodes[0].Name);
-
-			//mxd. Save ImageBrowserControl settings
-			General.Settings.WriteSetting("windows." + configname + ".showtexturesfromsubdirs", ImageBrowserControl.ShowTexturesFromSubDirectories);
-			if(General.Map.Config.UseLongTextureNames) General.Map.Options.UseLongTextureNames = ImageBrowserControl.UseLongTextureNames;
 			
 			// Clean up
-			browser.CleanUp();
+			browser.OnClose("windows." + configname);
 		}
 
-		// Static method to browse for texture or flat
-		// Returns null when cancelled.
-		public static string Browse(IWin32Window parent, string select, bool browseFlats)
+		// Static method to browse for texture or flat.
+		public static string Browse(IWin32Window parent, string select, bool browseflats)
 		{
-			TextureBrowserForm browser = new TextureBrowserForm(select, browseFlats);
-			if(browser.ShowDialog(parent) == DialogResult.OK) return browser.SelectedName; // Return result
-			
-			// Cancelled
-			return select;
+			TextureBrowserForm browser = new TextureBrowserForm(select, browseflats);
+			return (browser.ShowDialog(parent) == DialogResult.OK ? browser.SelectedName : select);
 		}
 
 		// Item double clicked
-		private void browser_SelectedItemDoubleClicked()
+		private void browser_SelectedItemDoubleClicked(ImageBrowserItem item)
 		{
-			if(apply.Enabled) apply_Click(this, EventArgs.Empty);
+			if(item == null) return;
+			switch(item.ItemType)
+			{
+				case ImageBrowserItemType.IMAGE:
+					if(selectedset == null) throw new NotSupportedException("selectedset required!");
+					if(apply.Enabled) apply_Click(this, EventArgs.Empty);
+					break;
+
+				case ImageBrowserItemType.FOLDER_UP:
+					if(selectedset == null) throw new NotSupportedException("selectedset required!");
+					if(selectedset.Parent != null)
+					{
+						// Select the node
+						tvTextureSets.SelectedNodes.Clear();
+						tvTextureSets.SelectedNodes.Add(selectedset.Parent);
+						selectedset.Parent.EnsureVisible();
+
+						// Update textures list
+						selectedset = selectedset.Parent;
+					}
+					else
+					{
+						tvTextureSets.SelectedNodes.Clear();
+						selectedset = null;
+					}
+					FillImagesList();
+					break;
+
+				case ImageBrowserItemType.FOLDER:
+					// selectedset is null when at root level
+					TreeNodeCollection nodes = (selectedset == null ? tvTextureSets.Nodes : selectedset.Nodes); 
+					foreach(TreeNode child in nodes)
+					{
+						TreeNodeData data = (TreeNodeData)child.Tag;
+						if(data.FolderName == item.TextureName)
+						{
+							// Select the node
+							tvTextureSets.SelectedNodes.Clear();
+							tvTextureSets.SelectedNodes.Add(child);
+							child.EnsureVisible();
+
+							// Update textures list
+							selectedset = child;
+							FillImagesList();
+							break;
+						}
+					}
+					break;
+
+				default: throw new NotImplementedException("Unsupported ImageBrowserItemType");
+			}
 		}
 
 		// This fills the list of textures, depending on the selected texture set
 		private void FillImagesList()
 		{
+			//mxd. Show root items
+			if(selectedset == null)
+			{
+				FillCategoriesList();
+				return;
+			}
+			
 			// Get the selected texture set
-			IFilledTextureSet set = (selectedset.Tag as IFilledTextureSet);
+			IFilledTextureSet set = ((TreeNodeData)selectedset.Tag).Set;
 
 			// Start adding
-			browser.BeginAdding(set.Level, false); //mxd. Pass current folder level
+			browser.BeginAdding(false);
 
+			//mxd. Add "Browse up" item
+			if(selectedset.Parent != null)
+			{
+				TreeNodeData data = (TreeNodeData)selectedset.Parent.Tag;
+				browser.AddFolder(ImageBrowserItemType.FOLDER_UP, availgroup, data.FolderName);
+			}
+			else
+			{
+				browser.AddFolder(ImageBrowserItemType.FOLDER_UP, availgroup, "All Texture Sets");
+			}
+
+			//mxd. Add folders
+			foreach(TreeNode child in selectedset.Nodes)
+			{
+				TreeNodeData data = (TreeNodeData)child.Tag;
+				browser.AddFolder(ImageBrowserItemType.FOLDER, availgroup, data.FolderName);
+			}
+
+			// Add textures
 			if(browseflats) 
 			{
 				// Add all available flats
 				foreach(ImageData img in set.Flats)
-					browser.Add(img, img, availgroup);
+					browser.AddItem(img, availgroup);
 
 				// Add all used flats
 				foreach(ImageData img in set.Flats)
-					if(img.UsedInMap) browser.Add(img, img, usedgroup);
+					if(img.UsedInMap) browser.AddItem(img, usedgroup);
 			}
 			else
 			{
 				// Add all available textures and mark the images for temporary loading
 				foreach(ImageData img in set.Textures)
-					browser.Add(img, img, availgroup);
+					browser.AddItem(img, availgroup);
 
 				// Add all used textures and mark the images for permanent loading
 				foreach(ImageData img in set.Textures)
-					if(img.UsedInMap) browser.Add(img, img, usedgroup);
+					if(img.UsedInMap) browser.AddItem(img, usedgroup);
 			}
 			
 			// Done adding
 			browser.EndAdding();
 		}
 
+		private void FillCategoriesList()
+		{
+			// Start adding
+			browser.BeginAdding(false);
+
+			foreach(TreeNode node in tvTextureSets.Nodes)
+			{
+				TreeNodeData data = (TreeNodeData)node.Tag;
+				browser.AddFolder(ImageBrowserItemType.FOLDER, availgroup, data.FolderName);
+				browser.AddFolder(ImageBrowserItemType.FOLDER, usedgroup, data.FolderName);
+			}
+
+			// Done adding
+			browser.EndAdding();
+		}
+
 		// Help
-		private void TextureBrowserForm_HelpRequested(object sender, HelpEventArgs hlpevent)
+		private void TextureBrowserForm_HelpRequested(object sender, HelpEventArgs e)
 		{
 			General.ShowHelp("w_imagesbrowser.html");
-			hlpevent.Handled = true;
+			e.Handled = true;
 		}
 
 		private void TextureBrowserForm_Shown(object sender, EventArgs e)
 		{
-			if(selectedset != null) //mxd. Calling FillImagesList() from constructor leads to TERRIBLE load times. Why? I have no sodding idea...
-				FillImagesList();
+			//mxd. Calling FillImagesList() from constructor results in TERRIBLE load times. Why? I have no sodding idea...
+			if(selectedset != null) FillImagesList();
 			
 			// Select texture
 			if(selecttextureonfill != 0)
 			{
-				browser.SelectItem(selecttextureonfill, (usedgroupcollapsed ? availgroup : usedgroup)); //mxd. availgroup/usedgroup switch.
+				browser.SelectItem(selecttextureonfill, browser.SelectedGroup);
 				selecttextureonfill = 0;
 			}
 
-			//mxd. Focus the textbox. Calling this from TextureBrowserForm_Activated (like it's done in DB2) fails when the form is maximized. Again, I've no idea why...
-			browser.FocusTextbox();
+			//mxd. Focus the textures list. Calling this from TextureBrowserForm_Activated (like it's done in DB2) fails when the form is maximized. Again, I've no idea why...
+			browser.FocusList();
 		}
 
 		//mxd
diff --git a/Source/Core/Windows/TextureSetForm.Designer.cs b/Source/Core/Windows/TextureSetForm.Designer.cs
index 4309e0489..1702e861f 100644
--- a/Source/Core/Windows/TextureSetForm.Designer.cs
+++ b/Source/Core/Windows/TextureSetForm.Designer.cs
@@ -229,7 +229,6 @@ namespace CodeImp.DoomBuilder.Windows
 			this.matcheslist.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
 						| System.Windows.Forms.AnchorStyles.Left)
 						| System.Windows.Forms.AnchorStyles.Right)));
-			this.matcheslist.BrowseFlats = false;
 			this.matcheslist.HideInputBox = true;
 			this.matcheslist.Location = new System.Drawing.Point(18, 55);
 			this.matcheslist.Name = "matcheslist";
diff --git a/Source/Core/Windows/TextureSetForm.cs b/Source/Core/Windows/TextureSetForm.cs
index a4b0326f5..3203f9aa3 100644
--- a/Source/Core/Windows/TextureSetForm.cs
+++ b/Source/Core/Windows/TextureSetForm.cs
@@ -19,6 +19,7 @@
 using System;
 using System.Collections.Generic;
 using System.Windows.Forms;
+using CodeImp.DoomBuilder.Controls;
 using CodeImp.DoomBuilder.Data;
 using CodeImp.DoomBuilder.Config;
 
@@ -170,7 +171,7 @@ namespace CodeImp.DoomBuilder.Windows
 				{
 					bool ismatch = set.IsMatch(img);
 					if((ismatch && matchesbutton.Checked) || (!ismatch && nomatchesbutton.Checked))
-						matcheslist.Add(img, img, null, tooltiptext);
+						matcheslist.AddItem(img, null, tooltiptext);
 				}
 				
 				// If not already mixed, add flats as well
@@ -181,7 +182,7 @@ namespace CodeImp.DoomBuilder.Windows
 					{
 						bool ismatch = set.IsMatch(img);
 						if((ismatch && matchesbutton.Checked) || (!ismatch && nomatchesbutton.Checked))
-							matcheslist.Add(img, img, null, tooltiptext);
+							matcheslist.AddItem(img, null, tooltiptext);
 					}
 				}
 				
@@ -213,11 +214,10 @@ namespace CodeImp.DoomBuilder.Windows
 		}
 		
 		// Texture doubleclicked
-		private void matcheslist_SelectedItemDoubleClicked()
+		private void matcheslist_SelectedItemDoubleClicked(ImageBrowserItem item)
 		{
 			// Add texture name to the list
-			if(matcheslist.SelectedItem != null)
-				filters.Items.Add(matcheslist.SelectedItem.Text);
+			if(item != null) filters.Items.Add(item.TextureName);
 			
 			// Run the timer
 			filterstimer.Start();
diff --git a/Source/Plugins/BuilderEffects/Interface/JitterSectorsForm.Designer.cs b/Source/Plugins/BuilderEffects/Interface/JitterSectorsForm.Designer.cs
index ae05340d5..7285a3cb2 100644
--- a/Source/Plugins/BuilderEffects/Interface/JitterSectorsForm.Designer.cs
+++ b/Source/Plugins/BuilderEffects/Interface/JitterSectorsForm.Designer.cs
@@ -133,7 +133,6 @@
 			this.textureUpper.Size = new System.Drawing.Size(83, 112);
 			this.textureUpper.TabIndex = 2;
 			this.textureUpper.TextureName = "";
-			this.textureUpper.UsePreviews = true;
 			this.textureUpper.OnValueChanged += new System.EventHandler(this.textureUpper_OnValueChanged);
 			// 
 			// cbPegTop
@@ -156,7 +155,6 @@
 			this.textureLower.Size = new System.Drawing.Size(83, 112);
 			this.textureLower.TabIndex = 4;
 			this.textureLower.TextureName = "";
-			this.textureLower.UsePreviews = true;
 			this.textureLower.OnValueChanged += new System.EventHandler(this.textureLower_OnValueChanged);
 			// 
 			// cbPegBottom
diff --git a/Source/Plugins/BuilderModes/Interface/MakeDoorForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/MakeDoorForm.Designer.cs
index 7828826e2..57fda0fe2 100644
--- a/Source/Plugins/BuilderModes/Interface/MakeDoorForm.Designer.cs
+++ b/Source/Plugins/BuilderModes/Interface/MakeDoorForm.Designer.cs
@@ -50,7 +50,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface
 			this.doortexture.Size = new System.Drawing.Size(83, 105);
 			this.doortexture.TabIndex = 0;
 			this.doortexture.TextureName = "";
-			this.doortexture.UsePreviews = true;
 			// 
 			// label1
 			// 
@@ -80,7 +79,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface
 			this.ceilingtexture.Size = new System.Drawing.Size(83, 105);
 			this.ceilingtexture.TabIndex = 1;
 			this.ceilingtexture.TextureName = "";
-			this.ceilingtexture.UsePreviews = true;
 			// 
 			// floortexture
 			// 
@@ -90,7 +88,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface
 			this.floortexture.Size = new System.Drawing.Size(83, 105);
 			this.floortexture.TabIndex = 2;
 			this.floortexture.TextureName = "";
-			this.floortexture.UsePreviews = true;
 			// 
 			// label3
 			// 
@@ -144,7 +141,6 @@ namespace CodeImp.DoomBuilder.BuilderModes.Interface
 			this.tracktexture.Size = new System.Drawing.Size(83, 105);
 			this.tracktexture.TabIndex = 6;
 			this.tracktexture.TextureName = "";
-			this.tracktexture.UsePreviews = true;
 			// 
 			// label4
 			// 
diff --git a/Source/Plugins/BuilderModes/Interface/SectorDrawingOptionsPanel.Designer.cs b/Source/Plugins/BuilderModes/Interface/SectorDrawingOptionsPanel.Designer.cs
index 9d329ab64..0667649db 100644
--- a/Source/Plugins/BuilderModes/Interface/SectorDrawingOptionsPanel.Designer.cs
+++ b/Source/Plugins/BuilderModes/Interface/SectorDrawingOptionsPanel.Designer.cs
@@ -99,7 +99,6 @@
 			this.ceiling.Size = new System.Drawing.Size(68, 90);
 			this.ceiling.TabIndex = 30;
 			this.ceiling.TextureName = "";
-			this.ceiling.UsePreviews = true;
 			this.ceiling.OnValueChanged += new System.EventHandler(this.ceiling_OnValueChanged);
 			// 
 			// floor
@@ -110,7 +109,6 @@
 			this.floor.Size = new System.Drawing.Size(68, 90);
 			this.floor.TabIndex = 29;
 			this.floor.TextureName = "";
-			this.floor.UsePreviews = true;
 			this.floor.OnValueChanged += new System.EventHandler(this.floor_OnValueChanged);
 			// 
 			// cbOverrideFloorTexture
@@ -282,7 +280,6 @@
 			this.bottom.Size = new System.Drawing.Size(68, 90);
 			this.bottom.TabIndex = 25;
 			this.bottom.TextureName = "";
-			this.bottom.UsePreviews = true;
 			this.bottom.OnValueChanged += new System.EventHandler(this.bottom_OnValueChanged);
 			// 
 			// cbOverrideTopTexture
@@ -305,7 +302,6 @@
 			this.middle.Size = new System.Drawing.Size(68, 90);
 			this.middle.TabIndex = 24;
 			this.middle.TextureName = "";
-			this.middle.UsePreviews = true;
 			this.middle.OnValueChanged += new System.EventHandler(this.middle_OnValueChanged);
 			// 
 			// top
@@ -317,7 +313,6 @@
 			this.top.Size = new System.Drawing.Size(68, 90);
 			this.top.TabIndex = 23;
 			this.top.TextureName = "";
-			this.top.UsePreviews = true;
 			this.top.OnValueChanged += new System.EventHandler(this.top_OnValueChanged);
 			// 
 			// groupBox3
diff --git a/Source/Plugins/NodesViewer/NodesViewerMode.cs b/Source/Plugins/NodesViewer/NodesViewerMode.cs
index 7e712122e..a2a5b40ab 100644
--- a/Source/Plugins/NodesViewer/NodesViewerMode.cs
+++ b/Source/Plugins/NodesViewer/NodesViewerMode.cs
@@ -148,6 +148,21 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer
 				return false;
 			}
 
+			//mxd. ZDoom SEGS overflow error
+			if(numsegs >= ushort.MaxValue)
+			{
+				// Cancel mode
+				MessageBox.Show("The map has too many SEGS (" + numsegs + "/" + ushort.MaxValue + ").\nIt won't load in most Doom source ports.", "THY SEGS ARETH WAAAY TOO PHAT!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+				General.Editing.CancelMode();
+				return false;
+			}
+
+			//mxd. Vanilla SEGS overflow warning
+			if(numsegs >= short.MaxValue)
+			{
+				MessageBox.Show("The map has too many SEGS (" + numsegs + "/" + short.MaxValue + ").\nIt won't load in Vanilla-style source ports.", "THY SEGS ARETH TOO PHAT!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+			}
+
 			segs = new Seg[numsegs];
 			for(int i = 0; i < segs.Length; i++)
 			{
@@ -199,8 +214,8 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer
 			ssectors = new Subsector[numssec];
 			for(int i = 0; i < ssectors.Length; i++)
 			{
-				ssectors[i].numsegs = ssecreader.ReadInt16();
-				ssectors[i].firstseg = ssecreader.ReadInt16();
+				ssectors[i].numsegs = ssecreader.ReadUInt16(); //TECH: these are short in Doom, ushort in ZDoom/PRBoom+
+				ssectors[i].firstseg = ssecreader.ReadUInt16();
 			}
 			ssecreader.Close();
 
@@ -344,7 +359,7 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer
 				// Boilerplate...
 				if(nodescount < 1) 
 				{
-					MessageBox.Show("The map has only one subsector.", "Why are you doing this, Stanley?..", MessageBoxButtons.OK, MessageBoxIcon.Error);
+					MessageBox.Show("The map has only one subsector.\nPlease add more sectors before using this mode.", "Why are you doing this, Stanley?..", MessageBoxButtons.OK, MessageBoxIcon.Error);
 					return false;
 				}
 
-- 
GitLab