diff --git a/Build/Scripting/ZDoom_DECORATE.cfg b/Build/Scripting/ZDoom_DECORATE.cfg
index 644afae1fbecb378040ae36ab7b478d766c3cf24..bdc1a7cbebb7569b088b5745d2c7727a6bd469ae 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 9d61402537b138d90b36a28ea53086cf4b758494..184b8b34485914053016a5d91c6bef02866faf98 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 b88a647193e90fda44e9b55ca94e511b2a89d56d..fdc247c60d188249752a2cc25e030816f84ebffa 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 2c1c63538dd5c77279c9c46eb35c5fd42d8bf59a..bf9453f440c941cecef05618884944b077a959d0 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 8cecfb91f8ab11bda4199afe477bcdc20b6ca2ae..0493be733ea1d275bb37f167c392cda9e66ba69c 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 e6f52782927fe232b86a50a0ca56a61e00a6b0f0..1df5a46b48d8d042fdfbfdbdade2210000507406 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 a0d287ce50db1871a7d842bbf1a8d25e2cd2f6d2..bd4fecf32a95394257c05135eb074052259a14d2 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 0000000000000000000000000000000000000000..ab8bfa6dcda1a464e5a5ed5a8184c541d148345b
--- /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 e376addfca62a876523fab8e6040a71cafae7281..6b2f44070102ca4df9a7bae15256c7536820c706 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 7a0e4cd922e138401aec5746215df3f2f428a063..980437c654ff568ada7f1215c17fb4c38288c218 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 39dc5d305f21d4701c2802b4a37e0fb094ea297c..cb19257e984a118d3701043e7f28883b54071f45 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 aafec37e2134636e39799f8552a193c72d77ad28..1142220f1894b01381dd7833d36f9abc1f642251 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 90e45cff0e47b160f9c33695befbf646ab7c7eaf..dd3eebeddf44bcd6d83638fdfe156eb8573e3ae7 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 46f39d460491495b31be0509ad0f6c6f054ffd55..40fcf8e7c5d01ff665144c963997b64218d31055 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 0000000000000000000000000000000000000000..0cb3276360a44fa671da29ffb443377fa103c4c8
--- /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 4c6cfb2571632c115be2bfacaf67b3afdc5c51a1..759423411080d9c75a9274a0b42c81b10c2b1bb2 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 e114e7b6a2ed5d3bef975e83eaae945305a398c2..400541b3b76b2c6c734893d35027ee9645cac0db 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 9f5d580c6a75b9fd64b5d023243b12f705c9b953..f2122be9caf1d59c6feb7e99e2cad3709cf55243 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 0000000000000000000000000000000000000000..a49c4d88a7ba61aa7a0b6ed603dcb4ddf1b2b679
--- /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 89d333cac4950e5aa5269ead88ddef3d07825da4..d2ff76632bb13d0c3d0dc869a2ed982133a5e0d1 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 0a59baa435f3f4f565b43157d00e13a89a12e634..f4e3019a6ec35b8f78188138319b197682974ff4 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 5d640fb44e8c509a7c488f384aaca309f5ecab1c..41dd4d944c44fc42a073c8842a105dc48bdd195c 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 043c0440f12315e2cb648b29a700190bebb23e2f..9ad7c6dbcfe1d2e8a9fb75a017652b99c08ed1c7 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 9baa95d3d801fa7f1257d8d213fc4c9f19e6b11e..8e58ed00d51e5942cd4be6aa63923fa97ae3f4a6 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 cd9fbe158c9e6c1212dc3de294bcf06ea4b1d9cc..fff29db500d4f0438a1f78a2e443f21d135bbdf0 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 35ba688189863b8665a66b9f0d5a7829743b20f6..84245c71c6dea6647043fb66b3ae7ded09a25cd9 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 e02f7ac0901ed896aa38b33fe2006efeeb18a5c6..437f642273c46421f6e86d45cb7ead5ab73cd5bf 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
Binary files /dev/null and b/Source/Core/Resources/Folder96.png differ
diff --git a/Source/Core/Resources/Folder96Up.png b/Source/Core/Resources/Folder96Up.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f98530ab5aaf7646c598919a45a72cc7ec9de75
Binary files /dev/null and b/Source/Core/Resources/Folder96Up.png differ
diff --git a/Source/Core/Windows/LinedefEditForm.Designer.cs b/Source/Core/Windows/LinedefEditForm.Designer.cs
index 4f8163d83256334c0c8f9cd0b80cf26edfedef02..aa9ef86e9e485b67b57faf897bb56d91dd14edca 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 d731d563054a185479e52bc220697fffbae39305..2c38ab769ac8c8b309e83e9423226e0390113e83 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 5d5dce0aa771f32fd94e5164a7ee42bd64f4e2c3..b0188d6777da2bf188371c17ad771128d4d8d88a 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 194b9d5d997e77139e40ab1781bf1c2c79ff8f27..8da4ec2f890c70339dbc9a70ce8e97ee17ed74d4 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 e1984e2abba4cc3490f4963af8f07fab017dbf57..0ca9a4619d84b32b7ec476c9c442c20ad387368e 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 108af1809ff948ec3490168617a33f45f4e87011..cb9c540c69124d894fa235f4017f8e93d254cf5b 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 7f3c7d73690f20dc74f8152eae91291694e290b8..e8095ff9cf388400a3949ea1a4da81e940a6d785 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 e0a9f8806ad66a81ca8c1b81f4eed8d9c102e853..7f637e0471d2d64227b01fb0c40cf94ac03bb330 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 c78069a26a27a8958f4804c2f44034f686fcc643..6cbcdc57763ed1948f69b7bf2aa574e786b7fe12 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 1276b4d35e53a6905c642687a3e28cc05f39d88c..d076ed4df3a2759c401493dbad074f8f871c1ee6 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 d5667897b2f65bd1cebc330d3361d95547738b15..be36e1282d7124e6dcb6fd21e2a727a6f1fd7096 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 4309e048950c3382b6ac9fc927e39421943d0c33..1702e861f1c6e0c2f6774cdf556338a2e9d60154 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 a4b0326f552bb5427a9da576890fc84849599f2d..3203f9aa3d11590939171f4b2652ed112372e31e 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 ae05340d563a54e8741736ff4adab25847729fca..7285a3cb2eebff3b4e5e9bdf356db789bb335f25 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 7828826e25f69c01cd93efac70c199bb09194691..57fda0fe2bf523e626a3b41c087b401a7f2cafa8 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 9d329ab6476c5679b9815a163f73d8e5bfb028f8..0667649db2f61aa4f6fece700fd3603306b83bb1 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 7e712122e54d3bfb1840604f414604d609e8468b..a2a5b40aba4debed0f88b4b0ede0bfbb9d7600c6 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;
 				}