UltimateZoneBuilder/Source/Controls/ImageBrowserControl.cs

487 lines
12 KiB
C#
Raw Normal View History

#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.Windows.Forms;
using Microsoft.Win32;
using System.Diagnostics;
using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Rendering;
2007-11-04 22:19:30 +00:00
using SlimDX.Direct3D9;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
#endregion
namespace CodeImp.DoomBuilder.Controls
{
2008-01-02 21:49:43 +00:00
internal partial class ImageBrowserControl : UserControl
{
#region ================== Constants
#endregion
2007-11-04 22:19:30 +00:00
#region ================== Delegates / Events
2007-11-04 22:19:30 +00:00
public delegate void SelectedItemChangedDelegate();
2008-10-01 12:42:30 +00:00
public delegate void SelectedItemDoubleClickDelegate();
2007-11-04 22:19:30 +00:00
public event SelectedItemChangedDelegate SelectedItemChanged;
2008-10-01 12:42:30 +00:00
public event SelectedItemDoubleClickDelegate SelectedItemDoubleClicked;
2007-11-04 22:19:30 +00:00
#endregion
#region ================== Variables
2008-10-01 12:42:30 +00:00
// Properties
private bool preventselection;
2007-11-04 22:19:30 +00:00
// States
private bool updating;
2008-10-01 12:42:30 +00:00
private int keepselected;
2007-11-04 22:19:30 +00:00
// All items
private List<ImageBrowserItem> items;
#endregion
#region ================== Properties
2008-10-01 12:42:30 +00:00
public bool PreventSelection { get { return preventselection; } set { preventselection = value; } }
public bool HideInputBox { get { return splitter.Panel2Collapsed; } set { splitter.Panel2Collapsed = value; } }
2007-11-04 22:19:30 +00:00
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
// Constructor
2007-12-26 14:29:36 +00:00
public ImageBrowserControl()
{
2007-10-31 22:16:53 +00:00
// Initialize
InitializeComponent();
items = new List<ImageBrowserItem>();
2007-11-04 22:19:30 +00:00
// Move textbox with label
objectname.Left = label.Right + label.Margin.Right + objectname.Margin.Left;
2007-10-31 22:16:53 +00:00
}
// This applies the application settings
public void ApplySettings()
2007-11-07 21:14:27 +00:00
{
// Force black background?
2007-12-01 01:32:56 +00:00
if(General.Settings.BlackBrowsers)
2007-11-07 21:14:27 +00:00
{
list.BackColor = Color.Black;
list.ForeColor = Color.White;
}
// Size of preview images
list.TileSize = new Size(General.Map.Data.Previews.MaxImageWidth + 26, General.Map.Data.Previews.MaxImageHeight + 26);
2007-11-07 21:14:27 +00:00
}
// This cleans everything up
public virtual void CleanUp()
{
// Stop refresh timer
refreshtimer.Enabled = false;
}
2007-11-04 22:19:30 +00:00
#endregion
#region ================== Rendering
// Draw item
private void list_DrawItem(object sender, DrawListViewItemEventArgs e)
2007-10-31 22:16:53 +00:00
{
if(!updating) (e.Item as ImageBrowserItem).Draw(e.Graphics, e.Bounds);
}
// Refresher
2007-11-04 22:19:30 +00:00
private void refreshtimer_Tick(object sender, EventArgs e)
{
bool allpreviewsloaded = true;
2007-11-04 22:19:30 +00:00
// 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())
2007-11-04 22:19:30 +00:00
{
// 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();
2009-01-24 11:49:40 +00:00
UpdateTextureSizeLabel();
2007-11-04 22:19:30 +00:00
}
#endregion
#region ================== Events
2007-11-04 22:19:30 +00:00
// 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();
}
}
2007-11-04 22:19:30 +00:00
// Key pressed
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;
}
}
2008-10-01 12:42:30 +00:00
2007-11-04 22:19:30 +00:00
// Selection changed
private void list_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
2007-10-31 22:16:53 +00:00
{
2008-10-01 12:42:30 +00:00
// Prevent selecting?
if(preventselection)
{
foreach(ListViewItem i in list.SelectedItems) i.Selected = false;
}
else
{
// Raise event
if(SelectedItemChanged != null) SelectedItemChanged();
}
2009-01-24 11:49:40 +00:00
UpdateTextureSizeLabel();
2008-10-01 12:42:30 +00:00
}
// Doublelicking an item
private void list_DoubleClick(object sender, EventArgs e)
{
if(!preventselection && (list.SelectedItems.Count > 0))
if(SelectedItemDoubleClicked != null) SelectedItemDoubleClicked();
2007-10-31 22:16:53 +00:00
}
2009-01-24 11:49:40 +00:00
// 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;
}
2007-11-04 22:19:30 +00:00
#endregion
#region ================== Methods
// This selects an item by name
public void SelectItem(string name, ListViewGroup preferredgroup)
{
ListViewItem lvi = null;
2008-10-01 12:42:30 +00:00
// Not when selecting is prevented
if(preventselection) return;
// Search in preferred group first
if(preferredgroup != null)
{
foreach(ListViewItem item in list.Items)
{
if((item.Group == preferredgroup) && (string.Compare(item.Text, name, true) == 0))
{
lvi = item;
break;
}
}
}
2009-01-24 11:49:40 +00:00
// If nothing found yet, search all items
if(lvi == null)
{
foreach(ListViewItem item in list.Items)
{
if(string.Compare(item.Text, name, true) == 0)
{
lvi = item;
break;
}
}
}
// Select the item
if(lvi != null)
{
// Select this item
list.SelectedItems.Clear();
lvi.Selected = true;
lvi.EnsureVisible();
}
2009-01-24 11:49:40 +00:00
UpdateTextureSizeLabel();
}
2007-11-04 22:19:30 +00:00
// This performs item sleection by keys
private void SelectNextItem(SearchDirectionHint dir)
{
ListViewItem lvi;
Point spos;
2008-10-01 12:42:30 +00:00
// Not when selecting is prevented
if(preventselection) return;
2007-11-04 22:19:30 +00:00
// Nothing selected?
if(list.SelectedItems.Count == 0)
{
// Select first
SelectFirstItem();
2007-11-04 22:19:30 +00:00
}
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);
2007-11-04 22:19:30 +00:00
// Try finding 5 times in the given direction
for(int i = 0; i < 5; i++)
2007-11-04 22:19:30 +00:00
{
// 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();
}
2009-01-24 11:49:40 +00:00
UpdateTextureSizeLabel();
}
2008-10-01 12:42:30 +00:00
// This selectes the first item
private void SelectFirstItem()
{
ListViewItem lvi;
2008-10-01 12:42:30 +00:00
// 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;
2007-11-04 22:19:30 +00:00
lvi.EnsureVisible();
}
}
2009-01-24 11:49:40 +00:00
UpdateTextureSizeLabel();
}
2007-11-04 22:19:30 +00:00
// This adds a group
public ListViewGroup AddGroup(string name)
{
ListViewGroup grp = new ListViewGroup(name);
list.Groups.Add(grp);
return grp;
}
2007-11-04 22:19:30 +00:00
// This begins adding items
2008-10-01 12:42:30 +00:00
public void BeginAdding(bool keepselectedindex)
2007-11-04 22:19:30 +00:00
{
2008-10-01 12:42:30 +00:00
if(keepselectedindex && (list.SelectedItems.Count > 0))
keepselected = list.SelectedIndices[0];
else
keepselected = -1;
// Clean list
items.Clear();
// Stop updating
2007-11-04 22:19:30 +00:00
refreshtimer.Enabled = false;
}
2007-11-04 22:19:30 +00:00
// This ends adding items
public void EndAdding()
{
// Fill list with items
RefillList(true);
// Start updating
refreshtimer.Enabled = true;
2007-11-04 22:19:30 +00:00
}
// This adds an item
2007-11-04 22:19:30 +00:00
public void Add(string text, ImageData image, object tag, ListViewGroup group)
{
2007-11-04 22:19:30 +00:00
ImageBrowserItem i = new ImageBrowserItem(text, image, tag);
i.ListGroup = group;
i.Group = group;
items.Add(i);
}
2008-10-01 12:42:30 +00:00
// 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);
}
2007-11-04 22:19:30 +00:00
// This fills the list based on the objectname filter
private void RefillList(bool selectfirst)
2007-11-04 22:19:30 +00:00
{
List<ListViewItem> showitems = new List<ListViewItem>();
2007-11-04 22:19:30 +00:00
// Begin updating list
updating = true;
2008-10-01 14:17:52 +00:00
//list.SuspendLayout();
2007-11-04 22:19:30 +00:00
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
2007-11-04 22:19:30 +00:00
foreach(ImageBrowserItem i in items)
{
// Add item if valid
if(ValidateItem(i))
{
i.Group = i.ListGroup;
i.Selected = false;
2007-11-04 22:19:30 +00:00
showitems.Add(i);
}
}
2008-10-01 12:42:30 +00:00
2007-11-04 22:19:30 +00:00
// Fill list
list.Items.AddRange(showitems.ToArray());
2007-11-04 22:19:30 +00:00
// Done updating list
updating = false;
list.EndUpdate();
2008-10-01 14:17:52 +00:00
list.Invalidate();
//list.ResumeLayout();
2007-11-04 22:19:30 +00:00
2008-10-01 12:42:30 +00:00
// 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();
}
}
2007-11-04 22:19:30 +00:00
// Raise event
2008-10-01 12:42:30 +00:00
if((SelectedItemChanged != null) && !preventselection) SelectedItemChanged();
2009-01-24 11:49:40 +00:00
UpdateTextureSizeLabel();
}
2007-11-04 22:19:30 +00:00
// This validates an item
private bool ValidateItem(ImageBrowserItem i)
{
return i.Text.Contains(objectname.Text);
}
// This sends the focus to the textbox
public void FocusTextbox()
{
objectname.Focus();
}
2009-01-24 11:49:40 +00:00
// 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
}
}