diff --git a/Resources/Hourglass.png b/Resources/Hourglass.png
new file mode 100644
index 00000000..94c428c3
Binary files /dev/null and b/Resources/Hourglass.png differ
diff --git a/Source/Builder.csproj b/Source/Builder.csproj
index cf7615b9..d1045ede 100644
--- a/Source/Builder.csproj
+++ b/Source/Builder.csproj
@@ -130,6 +130,9 @@
OpenMapOptionsForm.cs
+
+ Component
+
Form
@@ -264,6 +267,7 @@
+
diff --git a/Source/Data/DataManager.cs b/Source/Data/DataManager.cs
index 7da81d22..cf19529e 100644
--- a/Source/Data/DataManager.cs
+++ b/Source/Data/DataManager.cs
@@ -325,7 +325,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Load image
walker.Current.Value.LoadImage();
- //walker.Current.Value.CreateTexture();
+ //walker.Current.Value.CreateTexture(); // Impossible from different thread
}
// Wait a bit
diff --git a/Source/Data/ImageData.cs b/Source/Data/ImageData.cs
index 8e37686f..6de3a038 100644
--- a/Source/Data/ImageData.cs
+++ b/Source/Data/ImageData.cs
@@ -27,6 +27,7 @@ using System.Drawing.Imaging;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.IO;
using System.IO;
+using System.Windows.Forms;
#endregion
@@ -67,7 +68,7 @@ namespace CodeImp.DoomBuilder.Data
public string Name { get { return name; } }
public long LongName { get { return longname; } }
public PixelColorBlock PixelData { get { lock(this) { return pixeldata; } } }
- public Bitmap Bitmap { get { lock(this) { return bitmap; } } }
+ public Bitmap Bitmap { get { lock(this) { if(bitmap != null) return bitmap; else return CodeImp.DoomBuilder.Properties.Resources.Hourglass; } } }
public Texture Texture { get { lock(this) { return texture; } } }
public bool IsLoaded { get { return (bitmap != null); } }
public bool IsDisposed { get { return isdisposed; } }
diff --git a/Source/General/General.cs b/Source/General/General.cs
index a3eb1c51..da02e8e5 100644
--- a/Source/General/General.cs
+++ b/Source/General/General.cs
@@ -33,6 +33,8 @@ using CodeImp.DoomBuilder.Controls;
using System.Diagnostics;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Config;
+using SlimDX.Direct3D9;
+using System.Drawing;
#endregion
@@ -368,6 +370,10 @@ namespace CodeImp.DoomBuilder
{
Uri localpath;
Version thisversion;
+
+ // Enable OS visual styles
+ Application.EnableVisualStyles();
+ Application.DoEvents(); // This must be here to work around a .NET bug
// Get a reference to this assembly
thisasm = Assembly.GetExecutingAssembly();
@@ -416,6 +422,10 @@ namespace CodeImp.DoomBuilder
mainwindow.Show();
mainwindow.Update();
+ // Start Direct3D
+ General.WriteLogLine("Starting Direct3D graphics driver...");
+ Direct3D.Initialize();
+
// Load game configurations
General.WriteLogLine("Loading game configurations...");
LoadAllGameConfigurations();
@@ -519,6 +529,7 @@ namespace CodeImp.DoomBuilder
mainwindow.Dispose();
actions.Dispose();
clock.Dispose();
+ Direct3D.Terminate();
// Save colors
colors.SaveColors(settings);
@@ -934,6 +945,73 @@ namespace CodeImp.DoomBuilder
return dirname;
}
+ // This shows an image in a panel either zoomed or centered depending on size
+ public static void DisplayZoomedImage(Panel panel, Image image)
+ {
+ // Set the image
+ panel.BackgroundImage = image;
+
+ // Image not null?
+ if(image != null)
+ {
+ // Small enough to fit in panel?
+ if((image.Size.Width < panel.ClientRectangle.Width) &&
+ (image.Size.Height < panel.ClientRectangle.Height))
+ {
+ // Display centered
+ panel.BackgroundImageLayout = ImageLayout.Center;
+ }
+ else
+ {
+ // Display zoomed
+ panel.BackgroundImageLayout = ImageLayout.Zoom;
+ }
+ }
+ }
+
+ // This calculates the new rectangle when one is scaled into another keeping aspect ratio
+ public static RectangleF MakeZoomedRect(Size source, RectangleF target)
+ {
+ return MakeZoomedRect(new SizeF((int)source.Width, (int)source.Height), target);
+ }
+
+ // This calculates the new rectangle when one is scaled into another keeping aspect ratio
+ public static RectangleF MakeZoomedRect(Size source, Rectangle target)
+ {
+ return MakeZoomedRect(new SizeF((int)source.Width, (int)source.Height),
+ new RectangleF((int)target.Left, (int)target.Top, (int)target.Width, (int)target.Height));
+ }
+
+ // This calculates the new rectangle when one is scaled into another keeping aspect ratio
+ public static RectangleF MakeZoomedRect(SizeF source, RectangleF target)
+ {
+ float scale;
+
+ // Image fits?
+ if((source.Width <= target.Width) &&
+ (source.Height <= target.Height))
+ {
+ // Just center
+ scale = 1.0f;
+ }
+ // Image is wider than tall?
+ else if((source.Width - target.Width) > (source.Height - target.Height))
+ {
+ // Scale down by width
+ scale = target.Width / source.Width;
+ }
+ else
+ {
+ // Scale down by height
+ scale = target.Height / source.Height;
+ }
+
+ // Return centered and scaled
+ return new RectangleF(target.Left + (target.Width - source.Width * scale) * 0.5f,
+ target.Top + (target.Height - source.Height * scale) * 0.5f,
+ source.Width * scale, source.Height * scale);
+ }
+
#endregion
[Action(Action.TESTACTION)]
diff --git a/Source/Interface/ImageBrowser.Designer.cs b/Source/Interface/ImageBrowser.Designer.cs
index 060393f1..46f542ba 100644
--- a/Source/Interface/ImageBrowser.Designer.cs
+++ b/Source/Interface/ImageBrowser.Designer.cs
@@ -17,7 +17,6 @@ namespace CodeImp.DoomBuilder.Interface
{
components.Dispose();
}
- if(graphics != null) graphics.Dispose();
base.Dispose(disposing);
}
@@ -29,9 +28,15 @@ namespace CodeImp.DoomBuilder.Interface
///
private void InitializeComponent()
{
+ this.components = new System.ComponentModel.Container();
this.splitter = new System.Windows.Forms.SplitContainer();
- this.rendertarget = new CodeImp.DoomBuilder.Interface.RenderTargetControl();
+ this.list = new CodeImp.DoomBuilder.Interface.OptimizedListView();
+ this.images = new System.Windows.Forms.ImageList(this.components);
+ this.objectname = new System.Windows.Forms.TextBox();
+ this.label = new System.Windows.Forms.Label();
+ this.refreshtimer = new System.Windows.Forms.Timer(this.components);
this.splitter.Panel1.SuspendLayout();
+ this.splitter.Panel2.SuspendLayout();
this.splitter.SuspendLayout();
this.SuspendLayout();
//
@@ -46,32 +51,73 @@ namespace CodeImp.DoomBuilder.Interface
//
// splitter.Panel1
//
- this.splitter.Panel1.Controls.Add(this.rendertarget);
+ this.splitter.Panel1.Controls.Add(this.list);
+ //
+ // splitter.Panel2
+ //
+ this.splitter.Panel2.Controls.Add(this.objectname);
+ this.splitter.Panel2.Controls.Add(this.label);
this.splitter.Size = new System.Drawing.Size(518, 346);
- this.splitter.SplitterDistance = 310;
+ this.splitter.SplitterDistance = 312;
this.splitter.TabIndex = 0;
this.splitter.TabStop = false;
//
- // rendertarget
+ // list
//
- this.rendertarget.BackColor = System.Drawing.SystemColors.Window;
- this.rendertarget.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.rendertarget.Dock = System.Windows.Forms.DockStyle.Fill;
- this.rendertarget.Location = new System.Drawing.Point(0, 0);
- this.rendertarget.Name = "rendertarget";
- this.rendertarget.Size = new System.Drawing.Size(518, 310);
- this.rendertarget.TabIndex = 3;
+ this.list.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.list.LargeImageList = this.images;
+ this.list.Location = new System.Drawing.Point(0, 0);
+ this.list.MultiSelect = false;
+ this.list.Name = "list";
+ this.list.OwnerDraw = true;
+ this.list.Size = new System.Drawing.Size(518, 312);
+ this.list.Sorting = System.Windows.Forms.SortOrder.Ascending;
+ this.list.TabIndex = 0;
+ this.list.UseCompatibleStateImageBehavior = false;
+ this.list.DrawItem += new System.Windows.Forms.DrawListViewItemEventHandler(this.list_DrawItem);
+ this.list.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.list_ItemSelectionChanged);
+ //
+ // images
+ //
+ this.images.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
+ this.images.ImageSize = new System.Drawing.Size(64, 64);
+ this.images.TransparentColor = System.Drawing.Color.Transparent;
+ //
+ // objectname
+ //
+ this.objectname.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
+ this.objectname.Location = new System.Drawing.Point(145, 10);
+ this.objectname.Name = "objectname";
+ this.objectname.Size = new System.Drawing.Size(122, 20);
+ this.objectname.TabIndex = 0;
+ this.objectname.TextChanged += new System.EventHandler(this.objectname_TextChanged);
+ this.objectname.KeyDown += new System.Windows.Forms.KeyEventHandler(this.objectname_KeyDown);
+ //
+ // label
+ //
+ this.label.AutoSize = true;
+ this.label.Location = new System.Drawing.Point(1, 13);
+ this.label.Name = "label";
+ this.label.Size = new System.Drawing.Size(138, 14);
+ this.label.TabIndex = 0;
+ this.label.Text = "Select or type object name:";
+ //
+ // refreshtimer
+ //
+ this.refreshtimer.Interval = 500;
+ this.refreshtimer.Tick += new System.EventHandler(this.refreshtimer_Tick);
//
// ImageBrowser
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 14F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.splitter);
- this.DoubleBuffered = true;
this.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Name = "ImageBrowser";
this.Size = new System.Drawing.Size(518, 346);
this.splitter.Panel1.ResumeLayout(false);
+ this.splitter.Panel2.ResumeLayout(false);
+ this.splitter.Panel2.PerformLayout();
this.splitter.ResumeLayout(false);
this.ResumeLayout(false);
@@ -80,7 +126,11 @@ namespace CodeImp.DoomBuilder.Interface
#endregion
private System.Windows.Forms.SplitContainer splitter;
- private RenderTargetControl rendertarget;
+ private OptimizedListView list;
+ private System.Windows.Forms.ImageList images;
+ private System.Windows.Forms.Timer refreshtimer;
+ private System.Windows.Forms.TextBox objectname;
+ private System.Windows.Forms.Label label;
}
}
diff --git a/Source/Interface/ImageBrowser.cs b/Source/Interface/ImageBrowser.cs
index 5c97f381..1fe295e4 100644
--- a/Source/Interface/ImageBrowser.cs
+++ b/Source/Interface/ImageBrowser.cs
@@ -28,6 +28,9 @@ using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Rendering;
+using SlimDX.Direct3D9;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
#endregion
@@ -35,27 +38,29 @@ namespace CodeImp.DoomBuilder.Interface
{
public partial class ImageBrowser : UserControl
{
- #region ================== Constants
+ #region ================== Delegates / Events
- private const int ITEM_WIDTH = 80;
- private const int ITEM_HEIGHT = 92;
+ public delegate void SelectedItemChangedDelegate();
+ public event SelectedItemChangedDelegate SelectedItemChanged;
+
#endregion
#region ================== Variables
- // Graphics device for rendering
- private D3DDevice graphics;
+ // States
+ private bool updating;
- // Items list
+ // All items
private List items;
#endregion
#region ================== Properties
- public int Count { get { return items.Count; } }
-
+ public string LabelText { get { return label.Text; } set { label.Text = value; objectname.Left = label.Right + label.Margin.Right + objectname.Margin.Left; } }
+ public ListViewItem SelectedItem { get { if(list.SelectedItems.Count > 0) return list.SelectedItems[0]; else return null; } }
+
#endregion
#region ================== Constructor / Disposer
@@ -65,72 +70,198 @@ namespace CodeImp.DoomBuilder.Interface
{
// Initialize
InitializeComponent();
-
- // Make items list
items = new List();
-
- rendertarget.SetBounds(0, 0, 0, 10000, BoundsSpecified.Height);
- rendertarget.ClientSize = new Size(0, 10000);
+
+ // Move textbox with label
+ objectname.Left = label.Right + label.Margin.Right + objectname.Margin.Left;
}
- // Destructor
- ~ImageBrowser()
+ #endregion
+
+ #region ================== Rendering
+
+ // Draw item
+ private void list_DrawItem(object sender, DrawListViewItemEventArgs e)
{
- // Clean up
- if(graphics != null) graphics.Dispose();
+ if(!updating)
+ e.Graphics.DrawImageUnscaled((e.Item as ImageBrowserItem).GetImage(e.Bounds), e.Bounds);
}
+ // Resfresher
+ private void refreshtimer_Tick(object sender, EventArgs e)
+ {
+ // Go for all items
+ foreach(ImageBrowserItem i in list.Items)
+ {
+ // Items needs to be redrawn?
+ if(i.CheckRedrawNeeded(i.Bounds))
+ {
+ // Redraw item
+ i.GetImage(i.Bounds);
+
+ // Refresh item in list
+ list.RedrawItems(i.Index, i.Index, false);
+ }
+ }
+
+ // Continue refreshing only when still loading data
+ refreshtimer.Enabled = General.Map.Data.IsLoading;
+ }
+
#endregion
#region ================== Events
- // When resized
- protected override void OnResize(EventArgs e)
+ // Name typed
+ private void objectname_TextChanged(object sender, EventArgs e)
{
- // Redraw
- Redraw();
-
- // Call base
- base.OnResize(e);
+ RefillList();
+ if((list.SelectedItems.Count == 0) && (list.Items.Count > 0)) list.Items[0].Selected = true;
}
- #endregion
-
- #region ================== Rendering
-
- // Initialize
- public void InitializeGraphics()
+ // Key pressed
+ private void objectname_KeyDown(object sender, KeyEventArgs e)
{
- // Make graphics device
- graphics = new D3DDevice(rendertarget);
- graphics.Initialize();
+ // 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;
+ }
}
-
- // This redraws the list
- public void Redraw()
- {
- int numitemswide;
- // Calculate number of items wide
- numitemswide = (int)Math.Floor((float)ClientSize.Width / (float)ITEM_WIDTH);
+ // Selection changed
+ private void list_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
+ {
+ // Raise event
+ if(SelectedItemChanged != null) SelectedItemChanged();
}
#endregion
-
+
#region ================== Methods
- // This adds an item
- public void Add(string text, ImageData image, object tag)
+ // This performs item sleection by keys
+ private void SelectNextItem(SearchDirectionHint dir)
{
- ImageBrowserItem i;
-
- // Make new item
- i = new ImageBrowserItem(text, image, tag);
+ ListViewItem lvi;
+ Point spos;
- // Add item to list
+ // Nothing selected?
+ if(list.SelectedItems.Count == 0)
+ {
+ // Select first
+ if(list.Items.Count > 0)
+ {
+ lvi = list.FindNearestItem(SearchDirectionHint.Right, new Point(0, 0));
+ if(lvi != null) lvi.Selected = true;
+ lvi.EnsureVisible();
+ }
+ }
+ else
+ {
+ // Get selected item
+ lvi = list.SelectedItems[0];
+
+ // Determine point to start searching from
+ switch(dir)
+ {
+ case SearchDirectionHint.Left: spos = new Point(lvi.Bounds.Left - 1, lvi.Bounds.Top + 1); break;
+ case SearchDirectionHint.Right: spos = new Point(lvi.Bounds.Left + 1, lvi.Bounds.Top + 1); break;
+ case SearchDirectionHint.Up: spos = new Point(lvi.Bounds.Left + 1, lvi.Bounds.Top - 1); break;
+ case SearchDirectionHint.Down: spos = new Point(lvi.Bounds.Left + 1, lvi.Bounds.Bottom + 1); break;
+ default: spos = new Point(0, 0); break;
+ }
+
+ // Find next item
+ //lvi = list.SelectedItems[0].FindNearestItem(dir);
+ lvi = list.FindNearestItem(dir, spos);
+ if(lvi != null)
+ {
+ // Select next item
+ list.SelectedItems.Clear();
+ lvi.Selected = true;
+ lvi.EnsureVisible();
+ }
+ }
+ }
+
+ // This adds a group
+ public ListViewGroup AddGroup(string name)
+ {
+ ListViewGroup grp = new ListViewGroup(name);
+ list.Groups.Add(grp);
+ return grp;
+ }
+
+ // This begins adding items
+ public void BeginAdding()
+ {
+ refreshtimer.Enabled = false;
+ }
+
+ // This ends adding items
+ public void EndAdding()
+ {
+ RefillList();
+ refreshtimer.Enabled = true;
+ }
+
+ // This adds an item
+ public void Add(string text, ImageData image, object tag, ListViewGroup group)
+ {
+ ImageBrowserItem i = new ImageBrowserItem(text, image, tag);
+ i.ListGroup = group;
+ i.Group = group;
items.Add(i);
}
+ // This fills the list based on the objectname filter
+ private void RefillList()
+ {
+ List showitems = new List();
+
+ // 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();
+
+ // Go for all items NOT in the list
+ foreach(ImageBrowserItem i in items)
+ {
+ // Add item if valid
+ if(ValidateItem(i))
+ {
+ i.Group = i.ListGroup;
+ showitems.Add(i);
+ }
+ }
+
+ // Fill list
+ list.Items.AddRange(showitems.ToArray());
+
+ // Done updating list
+ updating = false;
+ list.EndUpdate();
+ list.ResumeLayout();
+
+ // Raise event
+ if(SelectedItemChanged != null) SelectedItemChanged();
+ }
+
+ // This validates an item
+ private bool ValidateItem(ImageBrowserItem i)
+ {
+ return i.Text.Contains(objectname.Text);
+ }
+
#endregion
}
}
diff --git a/Source/Interface/ImageBrowser.resx b/Source/Interface/ImageBrowser.resx
index a764f1c7..faff87e9 100644
--- a/Source/Interface/ImageBrowser.resx
+++ b/Source/Interface/ImageBrowser.resx
@@ -117,6 +117,24 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ True
+
+
+ True
+
+
+ 17, 17
+
+
+ True
+
+
+ True
+
+
+ 103, 17
+
True
diff --git a/Source/Interface/ImageBrowserItem.cs b/Source/Interface/ImageBrowserItem.cs
index 72adddaa..e2e577c0 100644
--- a/Source/Interface/ImageBrowserItem.cs
+++ b/Source/Interface/ImageBrowserItem.cs
@@ -28,25 +28,138 @@ using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Rendering;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using SlimDX.Direct3D;
#endregion
namespace CodeImp.DoomBuilder.Interface
{
- internal struct ImageBrowserItem
+ internal class ImageBrowserItem : ListViewItem
{
- // Variables
- public string text;
- public ImageData image;
- public object tag;
+ #region ================== Variables
+
+ // Display image
+ public ImageData icon;
+
+ // Group
+ private ListViewGroup listgroup;
+
+ // Image cache
+ private Image image;
+ private bool imageloaded;
+ private bool imageselected;
+
+ #endregion
+
+ #region ================== Properties
+
+ public ListViewGroup ListGroup { get { return listgroup; } set { listgroup = value; } }
+
+ #endregion
+
+ #region ================== Constructor / Disposer
// Constructors
- public ImageBrowserItem(string text, ImageData image, object tag)
+ public ImageBrowserItem(string text, ImageData icon, object tag)
{
// Initialize
- this.text = text;
- this.image = image;
- this.tag = tag;
+ this.Text = text;
+ this.icon = icon;
+ this.Tag = tag;
}
+
+ #endregion
+
+ #region ================== Methods
+
+ // This checks if a redraw is needed
+ public bool CheckRedrawNeeded(Rectangle bounds)
+ {
+ return ((image == null) || (image.Size != bounds.Size) ||
+ (this.Selected != imageselected) || (icon.IsLoaded && !imageloaded));
+ }
+
+ // This requests the cached image and redraws it if needed
+ public Image GetImage(Rectangle bounds)
+ {
+ Brush forecolor;
+ Brush backcolor;
+
+ // Do we need to redraw?
+ if(CheckRedrawNeeded(bounds))
+ {
+ // Keep settings
+ this.imageloaded = icon.IsLoaded;
+ this.imageselected = this.Selected;
+
+ // Trash old image
+ if(image != null) image.Dispose();
+
+ // Make a new image and graphics to draw with
+ image = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
+ Graphics g = Graphics.FromImage(image);
+ g.CompositingQuality = CompositingQuality.HighSpeed;
+ g.InterpolationMode = InterpolationMode.Bilinear;
+ g.SmoothingMode = SmoothingMode.HighQuality;
+ g.PixelOffsetMode = PixelOffsetMode.None;
+
+ // Determine coordinates
+ SizeF textsize = g.MeasureString(this.Text, this.ListView.Font, bounds.Width);
+ Size bordersize = new Size((bounds.Width - 64) >> 1, (bounds.Height - 64 - (int)textsize.Height) >> 1);
+ Rectangle imagerect = new Rectangle(bordersize.Width, bordersize.Height, 64, 64);
+ PointF textpos = new PointF(((float)bounds.Width - textsize.Width) * 0.5f, bounds.Height - textsize.Height - 2);
+
+ // Determine colors
+ if(this.Selected)
+ {
+ // Highlighted
+ backcolor = new LinearGradientBrush(new Point(0, 0), new Point(0, bounds.Height),
+ AdjustedColor(SystemColors.Highlight, 0.2f),
+ AdjustedColor(SystemColors.Highlight, -0.1f));
+ forecolor = SystemBrushes.HighlightText;
+ }
+ else
+ {
+ // Normal
+ backcolor = SystemBrushes.Window;
+ forecolor = SystemBrushes.WindowText;
+ }
+
+ // Draw!
+ g.FillRectangle(backcolor, 0, 0, bounds.Width, bounds.Height);
+ g.DrawImage(icon.Bitmap, General.MakeZoomedRect(icon.Bitmap.Size, imagerect));
+ g.DrawString(this.Text, this.ListView.Font, forecolor, textpos);
+
+ // Done
+ g.Dispose();
+ }
+
+ // Return image
+ return image;
+ }
+
+ // This brightens or darkens a color
+ private Color AdjustedColor(Color c, float amount)
+ {
+ ColorValue cc = ColorValue.FromColor(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());
+ }
+
+ // This clamps a value between 0 and 1
+ private float Saturate(float v)
+ {
+ if(v < 0f) return 0f; else if(v > 1f) return 1f; else return v;
+ }
+
+ #endregion
}
}
diff --git a/Source/Interface/LinedefInfoPanel.cs b/Source/Interface/LinedefInfoPanel.cs
index f82f4e35..224bf3d1 100644
--- a/Source/Interface/LinedefInfoPanel.cs
+++ b/Source/Interface/LinedefInfoPanel.cs
@@ -59,9 +59,9 @@ namespace CodeImp.DoomBuilder.Interface
fronthighname.Text = l.Front.HighTexture;
frontmidname.Text = l.Front.MiddleTexture;
frontlowname.Text = l.Front.LowTexture;
- fronthightex.BackgroundImage = General.Map.Data.GetTextureBitmap(l.Front.HighTexture);
- frontmidtex.BackgroundImage = General.Map.Data.GetTextureBitmap(l.Front.MiddleTexture);
- frontlowtex.BackgroundImage = General.Map.Data.GetTextureBitmap(l.Front.LowTexture);
+ General.DisplayZoomedImage(fronthightex, General.Map.Data.GetTextureBitmap(l.Front.HighTexture));
+ General.DisplayZoomedImage(frontmidtex, General.Map.Data.GetTextureBitmap(l.Front.MiddleTexture));
+ General.DisplayZoomedImage(frontlowtex, General.Map.Data.GetTextureBitmap(l.Front.LowTexture));
frontoffsetlabel.Enabled = true;
frontoffset.Enabled = true;
frontpanel.Enabled = true;
@@ -89,9 +89,9 @@ namespace CodeImp.DoomBuilder.Interface
backhighname.Text = l.Back.HighTexture;
backmidname.Text = l.Back.MiddleTexture;
backlowname.Text = l.Back.LowTexture;
- backhightex.BackgroundImage = General.Map.Data.GetTextureBitmap(l.Back.HighTexture);
- backmidtex.BackgroundImage = General.Map.Data.GetTextureBitmap(l.Back.MiddleTexture);
- backlowtex.BackgroundImage = General.Map.Data.GetTextureBitmap(l.Back.LowTexture);
+ General.DisplayZoomedImage(backhightex, General.Map.Data.GetTextureBitmap(l.Back.HighTexture));
+ General.DisplayZoomedImage(backmidtex, General.Map.Data.GetTextureBitmap(l.Back.MiddleTexture));
+ General.DisplayZoomedImage(backlowtex, General.Map.Data.GetTextureBitmap(l.Back.LowTexture));
backoffsetlabel.Enabled = true;
backoffset.Enabled = true;
backpanel.Enabled = true;
diff --git a/Source/Interface/OptimizedListView.cs b/Source/Interface/OptimizedListView.cs
new file mode 100644
index 00000000..78094e8c
--- /dev/null
+++ b/Source/Interface/OptimizedListView.cs
@@ -0,0 +1,64 @@
+
+#region ================== Copyright (c) 2007 Pascal vd Heiden
+
+/*
+ * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
+ * This program is released under GNU General Public License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#endregion
+
+#region ================== Namespaces
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Globalization;
+using System.Windows.Forms;
+using CodeImp.DoomBuilder.Controls;
+using CodeImp.DoomBuilder.Geometry;
+using CodeImp.DoomBuilder.Rendering;
+using CodeImp.DoomBuilder.Editing;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.Interface
+{
+ internal class OptimizedListView : ListView
+ {
+ #region ================== Constants
+
+ #endregion
+
+ #region ================== Variables
+
+ #endregion
+
+ #region ================== Properties
+
+ #endregion
+
+ #region ================== Constructor
+
+ // Constructor
+ public OptimizedListView() : base()
+ {
+ this.DoubleBuffered = true;
+ SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
+ }
+
+ #endregion
+
+ #region ================== Methods
+
+ #endregion
+ }
+}
diff --git a/Source/Interface/SectorInfoPanel.cs b/Source/Interface/SectorInfoPanel.cs
index 211bd262..56832f02 100644
--- a/Source/Interface/SectorInfoPanel.cs
+++ b/Source/Interface/SectorInfoPanel.cs
@@ -56,8 +56,8 @@ namespace CodeImp.DoomBuilder.Interface
brightness.Text = s.Brightness.ToString();
floorname.Text = s.FloorTexture;
ceilingname.Text = s.CeilTexture;
- floortex.BackgroundImage = General.Map.Data.GetFlatBitmap(s.FloorTexture);
- ceilingtex.BackgroundImage = General.Map.Data.GetFlatBitmap(s.CeilTexture);
+ General.DisplayZoomedImage(floortex, General.Map.Data.GetFlatBitmap(s.FloorTexture));
+ General.DisplayZoomedImage(ceilingtex, General.Map.Data.GetFlatBitmap(s.CeilTexture));
// Show the whole thing
this.Show();
diff --git a/Source/Interface/TextureBrowserForm.Designer.cs b/Source/Interface/TextureBrowserForm.Designer.cs
index f650b964..8ca222ed 100644
--- a/Source/Interface/TextureBrowserForm.Designer.cs
+++ b/Source/Interface/TextureBrowserForm.Designer.cs
@@ -28,26 +28,54 @@ namespace CodeImp.DoomBuilder.Interface
///
private void InitializeComponent()
{
- this.textures = new CodeImp.DoomBuilder.Interface.ImageBrowser();
+ this.browser = new CodeImp.DoomBuilder.Interface.ImageBrowser();
+ this.cancel = new System.Windows.Forms.Button();
+ this.apply = new System.Windows.Forms.Button();
this.SuspendLayout();
//
- // textures
+ // browser
//
- this.textures.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ this.browser.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.textures.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.textures.Location = new System.Drawing.Point(12, 12);
- this.textures.Name = "textures";
- this.textures.Size = new System.Drawing.Size(523, 350);
- this.textures.TabIndex = 0;
+ this.browser.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.browser.LabelText = "Select or enter a texture name:";
+ this.browser.Location = new System.Drawing.Point(11, 9);
+ this.browser.Name = "browser";
+ this.browser.Size = new System.Drawing.Size(649, 418);
+ this.browser.TabIndex = 0;
+ this.browser.SelectedItemChanged += new CodeImp.DoomBuilder.Interface.ImageBrowser.SelectedItemChangedDelegate(this.browser_SelectedItemChanged);
+ //
+ // cancel
+ //
+ this.cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancel.Location = new System.Drawing.Point(548, 404);
+ this.cancel.Name = "cancel";
+ this.cancel.Size = new System.Drawing.Size(112, 25);
+ this.cancel.TabIndex = 22;
+ this.cancel.Text = "Cancel";
+ this.cancel.UseVisualStyleBackColor = true;
+ //
+ // apply
+ //
+ this.apply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.apply.Location = new System.Drawing.Point(430, 404);
+ this.apply.Name = "apply";
+ this.apply.Size = new System.Drawing.Size(112, 25);
+ this.apply.TabIndex = 21;
+ this.apply.Text = "OK";
+ this.apply.UseVisualStyleBackColor = true;
//
// TextureBrowserForm
//
+ this.AcceptButton = this.apply;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
- this.ClientSize = new System.Drawing.Size(547, 374);
- this.Controls.Add(this.textures);
- this.DoubleBuffered = true;
+ this.CancelButton = this.cancel;
+ this.ClientSize = new System.Drawing.Size(672, 439);
+ this.Controls.Add(this.cancel);
+ this.Controls.Add(this.apply);
+ this.Controls.Add(this.browser);
this.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.MinimizeBox = false;
this.Name = "TextureBrowserForm";
@@ -60,6 +88,8 @@ namespace CodeImp.DoomBuilder.Interface
#endregion
- private ImageBrowser textures;
+ private ImageBrowser browser;
+ private System.Windows.Forms.Button cancel;
+ private System.Windows.Forms.Button apply;
}
}
\ No newline at end of file
diff --git a/Source/Interface/TextureBrowserForm.cs b/Source/Interface/TextureBrowserForm.cs
index ddeed653..d37e5503 100644
--- a/Source/Interface/TextureBrowserForm.cs
+++ b/Source/Interface/TextureBrowserForm.cs
@@ -27,6 +27,7 @@ using System.Diagnostics;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Config;
+using CodeImp.DoomBuilder.Map;
#endregion
@@ -37,14 +38,51 @@ namespace CodeImp.DoomBuilder.Interface
// Constructor
public TextureBrowserForm()
{
+ Dictionary usedtextures = new Dictionary();
+
// Initialize
InitializeComponent();
- // Add all textures
- foreach(ImageData img in General.Map.Data.Textures)
+ // Make groups
+ ListViewGroup used = browser.AddGroup("Used Textures");
+ ListViewGroup avail = browser.AddGroup("Available Textures");
+
+ // Go through the map to find the used textures
+ foreach(Sidedef sd in General.Map.Map.Sidedefs)
{
- textures.Add(img.Name, img, img);
+ // Add high texture
+ if(sd.HighTexture.Length > 0)
+ if(!usedtextures.ContainsKey(sd.LongHighTexture)) usedtextures.Add(sd.LongHighTexture, 0);
+
+ // Add mid texture
+ if(sd.LowTexture.Length > 0)
+ if(!usedtextures.ContainsKey(sd.LongMiddleTexture)) usedtextures.Add(sd.LongMiddleTexture, 0);
+
+ // Add low texture
+ if(sd.MiddleTexture.Length > 0)
+ if(!usedtextures.ContainsKey(sd.LongLowTexture)) usedtextures.Add(sd.LongLowTexture, 0);
}
+
+ // Start adding
+ browser.BeginAdding();
+
+ // Add all used textures
+ foreach(ImageData img in General.Map.Data.Textures)
+ if(usedtextures.ContainsKey(img.LongName))
+ browser.Add(img.Name, img, img, used);
+
+ // Add all available textures
+ foreach(ImageData img in General.Map.Data.Textures)
+ browser.Add(img.Name, img, img, avail);
+
+ // Done adding
+ browser.EndAdding();
+ }
+
+ // Selection changed
+ private void browser_SelectedItemChanged()
+ {
+ apply.Enabled = (browser.SelectedItem != null);
}
}
}
\ No newline at end of file
diff --git a/Source/Interface/TextureBrowserForm.resx b/Source/Interface/TextureBrowserForm.resx
index ff31a6db..2378acf1 100644
--- a/Source/Interface/TextureBrowserForm.resx
+++ b/Source/Interface/TextureBrowserForm.resx
@@ -117,4 +117,16 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
\ No newline at end of file
diff --git a/Source/Interface/ThingInfoPanel.cs b/Source/Interface/ThingInfoPanel.cs
index bae2a729..8d5b94fb 100644
--- a/Source/Interface/ThingInfoPanel.cs
+++ b/Source/Interface/ThingInfoPanel.cs
@@ -82,7 +82,7 @@ namespace CodeImp.DoomBuilder.Interface
tag.Text = ""; // TODO
angle.Text = t.AngleDeg.ToString() + "\u00B0";
spritename.Text = ti.Sprite;
- spritetex.BackgroundImage = General.Map.Data.GetSpriteBitmap(ti.Sprite);
+ General.DisplayZoomedImage(spritetex, General.Map.Data.GetSpriteBitmap(ti.Sprite));
// Show the whole thing
this.Show();
diff --git a/Source/Map/MapSet.cs b/Source/Map/MapSet.cs
index c914661b..5f90d676 100644
--- a/Source/Map/MapSet.cs
+++ b/Source/Map/MapSet.cs
@@ -487,7 +487,7 @@ namespace CodeImp.DoomBuilder.Map
if(vc.Value.Linedefs.Count == 0) vertices.Remove(vc);
}
}
-
+
#endregion
}
}
diff --git a/Source/Map/Sector.cs b/Source/Map/Sector.cs
index 3e011187..7667f53a 100644
--- a/Source/Map/Sector.cs
+++ b/Source/Map/Sector.cs
@@ -21,6 +21,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
+using CodeImp.DoomBuilder.IO;
#endregion
@@ -51,6 +52,8 @@ namespace CodeImp.DoomBuilder.Map
private int ceilheight;
private string floortexname;
private string ceiltexname;
+ private long longfloortexname;
+ private long longceiltexname;
private int effect;
private int tag;
private int brightness;
@@ -73,6 +76,8 @@ namespace CodeImp.DoomBuilder.Map
public int CeilHeight { get { return ceilheight; } }
public string FloorTexture { get { return floortexname; } }
public string CeilTexture { get { return ceiltexname; } }
+ public long LongFloorTexture { get { return longfloortexname; } }
+ public long LongCeilTexture { get { return longceiltexname; } }
public int Effect { get { return effect; } }
public int Tag { get { return tag; } }
public int Brightness { get { return brightness; } }
@@ -155,9 +160,9 @@ namespace CodeImp.DoomBuilder.Map
{
// Copy properties
s.ceilheight = ceilheight;
- s.ceiltexname = ceiltexname;
+ s.SetCeilTexture(ceiltexname);
s.floorheight = floorheight;
- s.floortexname = floortexname;
+ s.SetFloorTexture(floortexname);
s.effect = effect;
s.tag = tag;
s.brightness = brightness;
@@ -173,13 +178,27 @@ namespace CodeImp.DoomBuilder.Map
// Apply changes
this.floorheight = hfloor;
this.ceilheight = hceil;
- this.floortexname = tfloor;
- this.ceiltexname = tceil;
+ SetFloorTexture(tfloor);
+ SetCeilTexture(tceil);
this.effect = effect;
this.tag = tag;
this.brightness = brightness;
}
+ // This sets texture
+ public void SetFloorTexture(string name)
+ {
+ floortexname = name;
+ longfloortexname = Lump.MakeLongName(name);
+ }
+
+ // This sets texture
+ public void SetCeilTexture(string name)
+ {
+ ceiltexname = name;
+ longceiltexname = Lump.MakeLongName(name);
+ }
+
#endregion
}
}
diff --git a/Source/Map/Sidedef.cs b/Source/Map/Sidedef.cs
index 980ddce4..bbb8a073 100644
--- a/Source/Map/Sidedef.cs
+++ b/Source/Map/Sidedef.cs
@@ -21,6 +21,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
+using CodeImp.DoomBuilder.IO;
#endregion
@@ -53,6 +54,9 @@ namespace CodeImp.DoomBuilder.Map
private string texnamehigh;
private string texnamemid;
private string texnamelow;
+ private long longtexnamehigh;
+ private long longtexnamemid;
+ private long longtexnamelow;
// Disposing
private bool isdisposed = false;
@@ -72,6 +76,9 @@ namespace CodeImp.DoomBuilder.Map
public string HighTexture { get { return texnamehigh; } }
public string MiddleTexture { get { return texnamemid; } }
public string LowTexture { get { return texnamelow; } }
+ public long LongHighTexture { get { return longtexnamehigh; } }
+ public long LongMiddleTexture { get { return longtexnamemid; } }
+ public long LongLowTexture { get { return longtexnamelow; } }
#endregion
@@ -133,9 +140,9 @@ namespace CodeImp.DoomBuilder.Map
// Copy properties
s.offsetx = offsetx;
s.offsety = offsety;
- s.texnamehigh = texnamehigh;
- s.texnamelow = texnamelow;
- s.texnamemid = texnamemid;
+ s.SetTextureHigh(texnamehigh);
+ s.SetTextureMid(texnamelow);
+ s.SetTextureLow(texnamemid);
}
#endregion
@@ -148,9 +155,30 @@ namespace CodeImp.DoomBuilder.Map
// Apply changes
this.offsetx = offsetx;
this.offsety = offsety;
- this.texnamehigh = thigh;
- this.texnamemid = tmid;
- this.texnamelow = tlow;
+ SetTextureHigh(thigh);
+ SetTextureMid(tmid);
+ SetTextureLow(tlow);
+ }
+
+ // This sets texture
+ public void SetTextureHigh(string name)
+ {
+ texnamehigh = name;
+ longtexnamehigh = Lump.MakeLongName(name);
+ }
+
+ // This sets texture
+ public void SetTextureMid(string name)
+ {
+ texnamemid = name;
+ longtexnamemid = Lump.MakeLongName(name);
+ }
+
+ // This sets texture
+ public void SetTextureLow(string name)
+ {
+ texnamelow = name;
+ longtexnamelow = Lump.MakeLongName(name);
}
#endregion
diff --git a/Source/Properties/Resources.Designer.cs b/Source/Properties/Resources.Designer.cs
index 345dd71f..8a974c74 100644
--- a/Source/Properties/Resources.Designer.cs
+++ b/Source/Properties/Resources.Designer.cs
@@ -81,6 +81,13 @@ namespace CodeImp.DoomBuilder.Properties {
}
}
+ internal static System.Drawing.Bitmap Hourglass {
+ get {
+ object obj = ResourceManager.GetObject("Hourglass", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
internal static System.Drawing.Bitmap LinesMode {
get {
object obj = ResourceManager.GetObject("LinesMode", resourceCulture);
diff --git a/Source/Properties/Resources.resx b/Source/Properties/Resources.resx
index 87ed9287..8236842a 100644
--- a/Source/Properties/Resources.resx
+++ b/Source/Properties/Resources.resx
@@ -172,4 +172,7 @@
..\Resources\Filter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\Hourglass.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/Source/Rendering/D3DDevice.cs b/Source/Rendering/D3DDevice.cs
index 45cc1312..4aeea338 100644
--- a/Source/Rendering/D3DDevice.cs
+++ b/Source/Rendering/D3DDevice.cs
@@ -105,7 +105,6 @@ namespace CodeImp.DoomBuilder.Rendering
if(backbuffer != null) backbuffer.Dispose();
if(depthbuffer != null) depthbuffer.Dispose();
device.Dispose();
- Direct3D.Terminate();
// Done
isdisposed = true;
@@ -194,9 +193,6 @@ namespace CodeImp.DoomBuilder.Rendering
PresentParameters displaypp;
DeviceType devtype;
- // Start DirectX
- Direct3D.Initialize();
-
// Use default adapter
this.adapter = 0; // Manager.Adapters.Default.Adapter;
@@ -306,6 +302,12 @@ namespace CodeImp.DoomBuilder.Rendering
// Unload all Direct3D resources
foreach(ID3DResource res in resources) res.UnloadResource();
+ // Lose backbuffers
+ backbuffer.Dispose();
+ depthbuffer.Dispose();
+ backbuffer = null;
+ depthbuffer = null;
+
// Make present parameters
displaypp = CreatePresentParameters(adapter);
diff --git a/Source/Rendering/Renderer.cs b/Source/Rendering/Renderer.cs
index 8cde6f38..2ed5c2fe 100644
--- a/Source/Rendering/Renderer.cs
+++ b/Source/Rendering/Renderer.cs
@@ -76,6 +76,7 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.UnregisterResource(this);
// Done
+ graphics = null;
isdisposed = true;
}
}
diff --git a/Source/Resources/Hourglass.png b/Source/Resources/Hourglass.png
new file mode 100644
index 00000000..94c428c3
Binary files /dev/null and b/Source/Resources/Hourglass.png differ