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