mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-17 09:32:34 +00:00
UDMF map parser should work ~35% faster now. Texture browser form: keyboard focus was not updated when switching between textures using Tab key. "Graphics" folder is now checked when searching for texture patches. Various cosmetic changes here and there.
555 lines
14 KiB
C#
555 lines
14 KiB
C#
|
|
#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.Drawing;
|
|
using System.Windows.Forms;
|
|
using CodeImp.DoomBuilder.Data;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.Controls
|
|
{
|
|
internal partial class ImageBrowserControl : UserControl
|
|
{
|
|
#region ================== Constants
|
|
|
|
#endregion
|
|
|
|
#region ================== Delegates / Events
|
|
|
|
public delegate void SelectedItemChangedDelegate();
|
|
public delegate void SelectedItemDoubleClickDelegate();
|
|
|
|
public event SelectedItemChangedDelegate SelectedItemChanged;
|
|
public event SelectedItemDoubleClickDelegate SelectedItemDoubleClicked;
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
// Properties
|
|
private bool preventselection;
|
|
|
|
// States
|
|
private bool updating;
|
|
private int keepselected;
|
|
|
|
// All items
|
|
private List<ImageBrowserItem> items;
|
|
|
|
// Items visible in the list
|
|
private List<ImageBrowserItem> visibleitems;
|
|
|
|
//mxd
|
|
private static int mixMode;
|
|
|
|
#endregion
|
|
|
|
#region ================== Properties
|
|
|
|
public bool PreventSelection { get { return preventselection; } set { preventselection = value; } }
|
|
public bool HideInputBox { get { return splitter.Panel2Collapsed; } set { splitter.Panel2Collapsed = value; } }
|
|
//public string LabelText { get { return label.Text; } set { label.Text = value; objectname.Left = label.Right + label.Margin.Right + objectname.Margin.Left; } } //mxd
|
|
public ListViewItem SelectedItem { get { if(list.SelectedItems.Count > 0) return list.SelectedItems[0]; else return null; } }
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor / Disposer
|
|
|
|
// Constructor
|
|
public ImageBrowserControl()
|
|
{
|
|
// Initialize
|
|
InitializeComponent();
|
|
items = new List<ImageBrowserItem>();
|
|
|
|
//mxd.
|
|
StepsList sizes = new StepsList { 4, 8, 16, 32, 48, 64, 96, 128, 196, 256, 512, 1024 };
|
|
filterWidth.StepValues = sizes;
|
|
filterHeight.StepValues = sizes;
|
|
}
|
|
|
|
// This applies the application settings
|
|
public void ApplySettings()
|
|
{
|
|
// Force black background?
|
|
if(General.Settings.BlackBrowsers)
|
|
{
|
|
list.BackColor = Color.Black;
|
|
list.ForeColor = Color.White;
|
|
}
|
|
|
|
// 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;
|
|
if(General.Settings.ShowTextureSizes) itemheight += 12;
|
|
list.TileSize = new Size(itemwidth, itemheight);
|
|
|
|
//mxd
|
|
if(General.Map.Config.MixTexturesFlats) {
|
|
cbMixMode.SelectedIndex = mixMode;
|
|
} else {
|
|
labelMixMode.Visible = false;
|
|
cbMixMode.Visible = false;
|
|
label.Left = labelMixMode.Left;
|
|
objectname.Left = label.Right + label.Margin.Right + objectname.Margin.Left;
|
|
texturesizelabel.Left = objectname.Right + objectname.Margin.Right;
|
|
texturesize.Left = texturesizelabel.Right + texturesizelabel.Margin.Right;
|
|
mixMode = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// This cleans everything up
|
|
public virtual void CleanUp()
|
|
{
|
|
// Stop refresh timer
|
|
refreshtimer.Enabled = false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#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;
|
|
|
|
// 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();
|
|
}
|
|
}
|
|
|
|
// If all previews were loaded, stop this timer
|
|
if(allpreviewsloaded) refreshtimer.Stop();
|
|
|
|
UpdateTextureSizeLabel();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Events
|
|
|
|
// Name typed
|
|
private void objectname_TextChanged(object sender, EventArgs e)
|
|
{
|
|
// Update list
|
|
RefillList(false);
|
|
|
|
// No item selected?
|
|
if(list.SelectedItems.Count == 0)
|
|
{
|
|
// Select first
|
|
SelectFirstItem();
|
|
}
|
|
}
|
|
|
|
// Key pressed in textbox
|
|
private void objectname_KeyDown(object sender, KeyEventArgs 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;
|
|
|
|
// Tab
|
|
case Keys.Tab: GoToNextSameTexture(); e.SuppressKeyPress = true; break;
|
|
}
|
|
}
|
|
|
|
//mxd
|
|
private void filterSize_WhenTextChanged(object sender, EventArgs e) {
|
|
objectname_TextChanged(sender, e);
|
|
}
|
|
|
|
// Key pressed in list
|
|
private void list_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if(e.KeyData == Keys.Tab)
|
|
{
|
|
GoToNextSameTexture();
|
|
e.SuppressKeyPress = true;
|
|
}
|
|
}
|
|
|
|
// Selection changed
|
|
private void list_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
|
|
{
|
|
// Prevent selecting?
|
|
if(preventselection)
|
|
{
|
|
foreach(ListViewItem i in list.SelectedItems) i.Selected = false;
|
|
}
|
|
else
|
|
{
|
|
// Raise event
|
|
if(SelectedItemChanged != null) SelectedItemChanged();
|
|
}
|
|
|
|
UpdateTextureSizeLabel();
|
|
}
|
|
|
|
// Doublelicking an item
|
|
private void list_DoubleClick(object sender, EventArgs e)
|
|
{
|
|
if(!preventselection && (list.SelectedItems.Count > 0))
|
|
if(SelectedItemDoubleClicked != null) SelectedItemDoubleClicked();
|
|
}
|
|
|
|
// Control is resized
|
|
private void ImageBrowserControl_Resize(object sender, EventArgs e)
|
|
{
|
|
UpdateTextureSizeLabel();
|
|
}
|
|
|
|
// This hides the texture size label
|
|
private void texturesizetimer_Tick(object sender, EventArgs e)
|
|
{
|
|
texturesizetimer.Stop();
|
|
texturesize.Visible = false;
|
|
texturesizelabel.Visible = false;
|
|
}
|
|
|
|
//mxd
|
|
private void cbMixMode_SelectedIndexChanged(object sender, EventArgs e) {
|
|
mixMode = cbMixMode.SelectedIndex;
|
|
RefillList(false);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Methods
|
|
|
|
// This selects the next texture with the same name as the selected texture
|
|
public void GoToNextSameTexture()
|
|
{
|
|
if(list.SelectedItems.Count > 0)
|
|
{
|
|
ListViewItem selected = list.SelectedItems[0];
|
|
|
|
//mxd
|
|
foreach(ListViewItem n in visibleitems) {
|
|
if(n == selected) continue;
|
|
if(n.Text == selected.Text) {
|
|
n.Selected = true;
|
|
n.Focused = true;
|
|
n.EnsureVisible();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// This selects an item by name
|
|
public void SelectItem(string name, ListViewGroup preferredgroup)
|
|
{
|
|
ListViewItem lvi = null;
|
|
|
|
// Not when selecting is prevented
|
|
if(preventselection) return;
|
|
|
|
// Search in preferred group first
|
|
if(preferredgroup != null)
|
|
{
|
|
foreach(ListViewItem item in list.Items)
|
|
{
|
|
if(string.Compare(item.Text, name, true) == 0)
|
|
{
|
|
lvi = item;
|
|
if(item.Group == preferredgroup) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Select the item
|
|
if(lvi != null)
|
|
{
|
|
// Select this item
|
|
list.SelectedItems.Clear();
|
|
lvi.Selected = true;
|
|
lvi.EnsureVisible();
|
|
}
|
|
|
|
UpdateTextureSizeLabel();
|
|
}
|
|
|
|
// This performs item sleection by keys
|
|
private void SelectNextItem(SearchDirectionHint dir)
|
|
{
|
|
ListViewItem lvi;
|
|
Point spos;
|
|
|
|
// Not when selecting is prevented
|
|
if(preventselection) return;
|
|
|
|
// Nothing selected?
|
|
if(list.SelectedItems.Count == 0)
|
|
{
|
|
// Select first
|
|
SelectFirstItem();
|
|
}
|
|
else
|
|
{
|
|
// Get selected item
|
|
lvi = list.SelectedItems[0];
|
|
Rectangle lvirect = list.GetItemRect(lvi.Index, ItemBoundsPortion.Entire);
|
|
spos = new Point(lvirect.Location.X + lvirect.Width / 2, lvirect.Y + lvirect.Height / 2);
|
|
|
|
// Try finding 5 times in the given direction
|
|
for(int i = 0; i < 5; i++)
|
|
{
|
|
// Move point in given direction
|
|
switch(dir)
|
|
{
|
|
case SearchDirectionHint.Left: spos.X -= list.TileSize.Width / 2; break;
|
|
case SearchDirectionHint.Right: spos.X += list.TileSize.Width / 2; break;
|
|
case SearchDirectionHint.Up: spos.Y -= list.TileSize.Height / 2; break;
|
|
case SearchDirectionHint.Down: spos.Y += list.TileSize.Height / 2; break;
|
|
}
|
|
|
|
// Test position
|
|
lvi = list.GetItemAt(spos.X, spos.Y);
|
|
if(lvi != null)
|
|
{
|
|
// Select item
|
|
list.SelectedItems.Clear();
|
|
lvi.Selected = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Make selection visible
|
|
if(list.SelectedItems.Count > 0) list.SelectedItems[0].EnsureVisible();
|
|
}
|
|
|
|
UpdateTextureSizeLabel();
|
|
}
|
|
|
|
// This selectes the first item
|
|
private void SelectFirstItem()
|
|
{
|
|
ListViewItem lvi;
|
|
|
|
// Not when selecting is prevented
|
|
if(preventselection) return;
|
|
|
|
// Select first
|
|
if(list.Items.Count > 0)
|
|
{
|
|
list.SelectedItems.Clear();
|
|
lvi = list.GetItemAt(list.TileSize.Width / 2, list.TileSize.Height / 2);
|
|
if(lvi != null)
|
|
{
|
|
lvi.Selected = true;
|
|
lvi.EnsureVisible();
|
|
}
|
|
}
|
|
|
|
UpdateTextureSizeLabel();
|
|
}
|
|
|
|
// 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(bool keepselectedindex)
|
|
{
|
|
if(keepselectedindex && (list.SelectedItems.Count > 0))
|
|
keepselected = list.SelectedIndices[0];
|
|
else
|
|
keepselected = -1;
|
|
|
|
// Clean list
|
|
items.Clear();
|
|
|
|
// Stop updating
|
|
refreshtimer.Enabled = false;
|
|
}
|
|
|
|
// This ends adding items
|
|
public void EndAdding()
|
|
{
|
|
// Fill list with items
|
|
RefillList(true);
|
|
|
|
// Start updating
|
|
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 adds an item
|
|
public void Add(string text, ImageData image, object tag, ListViewGroup group, string tooltiptext)
|
|
{
|
|
ImageBrowserItem i = new ImageBrowserItem(text, image, tag);
|
|
i.ListGroup = group;
|
|
i.Group = group;
|
|
i.ToolTipText = tooltiptext;
|
|
items.Add(i);
|
|
}
|
|
|
|
// This fills the list based on the objectname filter
|
|
private void RefillList(bool selectfirst)
|
|
{
|
|
visibleitems = new List<ImageBrowserItem>();
|
|
|
|
// 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();
|
|
|
|
//mxd. Filtering by texture size?
|
|
int w = filterWidth.GetResult(-1);
|
|
int h = filterHeight.GetResult(-1);
|
|
|
|
// Go for all items
|
|
foreach(ImageBrowserItem i in items)
|
|
{
|
|
// Add item if valid
|
|
if(ValidateItem(i) && ValidateItemSize(i, w, h))
|
|
{
|
|
i.Group = i.ListGroup;
|
|
i.Selected = false;
|
|
visibleitems.Add(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();
|
|
|
|
// Make selection?
|
|
if(!preventselection && (list.Items.Count > 0))
|
|
{
|
|
// Select specific item?
|
|
if(keepselected > -1)
|
|
{
|
|
list.Items[keepselected].Selected = true;
|
|
list.Items[keepselected].EnsureVisible();
|
|
}
|
|
// Select first item?
|
|
else if(selectfirst)
|
|
{
|
|
SelectFirstItem();
|
|
}
|
|
}
|
|
|
|
// Raise event
|
|
if((SelectedItemChanged != null) && !preventselection) SelectedItemChanged();
|
|
UpdateTextureSizeLabel();
|
|
}
|
|
|
|
// This validates an item
|
|
private bool ValidateItem(ImageBrowserItem i)
|
|
{
|
|
//mxd. mixMode: 0 = All, 1 = Textures, 2 = Flats
|
|
if(!splitter.Panel2Collapsed) {
|
|
if(mixMode == 1 && i.icon.IsFlat) return false;
|
|
if(mixMode == 2 && !i.icon.IsFlat) return false;
|
|
}
|
|
|
|
return i.Text.Contains(objectname.Text);
|
|
}
|
|
|
|
//mxd. This validates an item's texture size
|
|
private bool ValidateItemSize(ImageBrowserItem i, int w, int h) {
|
|
if (!i.icon.IsPreviewLoaded) return true;
|
|
if (w > 0 && i.icon.Width != w) return false;
|
|
if (h > 0 && i.icon.Height != h) return false;
|
|
return true;
|
|
}
|
|
|
|
// This sends the focus to the textbox
|
|
public void FocusTextbox()
|
|
{
|
|
objectname.Focus();
|
|
}
|
|
|
|
// This updates the texture size label
|
|
private void UpdateTextureSizeLabel()
|
|
{
|
|
if((list.SelectedItems.Count == 0) ||
|
|
(splitter.Panel2.ClientSize.Width < (texturesize.Location.X + texturesize.Size.Width)))
|
|
{
|
|
texturesizetimer.Start();
|
|
}
|
|
else
|
|
{
|
|
texturesizetimer.Stop();
|
|
ImageBrowserItem lvi = (list.SelectedItems[0] as ImageBrowserItem);
|
|
if(lvi.icon.IsPreviewLoaded)
|
|
texturesize.Text = lvi.icon.Width + " x " + lvi.icon.Height;
|
|
else
|
|
texturesize.Text = "unknown";
|
|
texturesize.Visible = true;
|
|
texturesizelabel.Visible = true;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|