2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
#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.Windows.Forms;
|
|
|
|
using CodeImp.DoomBuilder.Config;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
namespace CodeImp.DoomBuilder.Controls
|
|
|
|
{
|
|
|
|
public partial class ThingBrowserControl : UserControl
|
|
|
|
{
|
|
|
|
#region ================== Events
|
|
|
|
|
|
|
|
public delegate void TypeChangedDeletegate(ThingTypeInfo value);
|
|
|
|
public delegate void TypeDoubleClickDeletegate();
|
|
|
|
|
|
|
|
public event TypeChangedDeletegate OnTypeChanged;
|
|
|
|
public event TypeDoubleClickDeletegate OnTypeDoubleClicked;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Variables
|
|
|
|
|
|
|
|
private List<TreeNode> nodes;
|
|
|
|
private ThingTypeInfo thinginfo;
|
|
|
|
private bool doupdatenode;
|
|
|
|
private bool doupdatetextbox;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Properties
|
|
|
|
|
|
|
|
public string TypeStringValue { get { return typeid.Text; } }
|
2013-07-11 11:43:49 +00:00
|
|
|
public bool UseMultiSelection { get { return typelist.UseMultiSelection; } set { typelist.UseMultiSelection = value; } }
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Constructor
|
|
|
|
|
|
|
|
// Constructor
|
|
|
|
public ThingBrowserControl()
|
|
|
|
{
|
|
|
|
InitializeComponent();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This sets up the control
|
|
|
|
public void Setup()
|
|
|
|
{
|
|
|
|
// Go for all predefined categories
|
|
|
|
typelist.Nodes.Clear();
|
|
|
|
nodes = new List<TreeNode>();
|
|
|
|
foreach(ThingCategory tc in General.Map.Data.ThingCategories)
|
|
|
|
{
|
|
|
|
// Create category
|
|
|
|
TreeNode cn = typelist.Nodes.Add(tc.Name, tc.Title);
|
|
|
|
if((tc.Color >= 0) && (tc.Color < thingimages.Images.Count)) cn.ImageIndex = tc.Color;
|
|
|
|
cn.SelectedImageIndex = cn.ImageIndex;
|
|
|
|
foreach(ThingTypeInfo ti in tc.Things)
|
|
|
|
{
|
|
|
|
// Create thing
|
|
|
|
TreeNode n = cn.Nodes.Add(ti.Title);
|
|
|
|
if((ti.Color >= 0) && (ti.Color < thingimages.Images.Count)) n.ImageIndex = ti.Color;
|
|
|
|
n.SelectedImageIndex = n.ImageIndex;
|
|
|
|
n.Tag = ti;
|
|
|
|
nodes.Add(n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
doupdatenode = true;
|
|
|
|
doupdatetextbox = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Methods
|
|
|
|
|
|
|
|
// Select a type
|
|
|
|
public void SelectType(int type)
|
|
|
|
{
|
|
|
|
// Set type index
|
|
|
|
typeid.Text = type.ToString();
|
|
|
|
typeid_TextChanged(this, EventArgs.Empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return selected type info
|
|
|
|
public ThingTypeInfo GetSelectedInfo()
|
|
|
|
{
|
|
|
|
return thinginfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This clears the type
|
|
|
|
public void ClearSelectedType()
|
|
|
|
{
|
|
|
|
doupdatenode = false;
|
|
|
|
|
|
|
|
// Clear selection
|
2013-07-11 11:43:49 +00:00
|
|
|
typelist.ClearSelectedNodes(); //mxd
|
2009-04-19 18:07:22 +00:00
|
|
|
typeid.Text = "";
|
|
|
|
|
|
|
|
// Collapse nodes
|
|
|
|
foreach(TreeNode n in nodes)
|
|
|
|
if(n.Parent.IsExpanded) n.Parent.Collapse();
|
|
|
|
|
|
|
|
doupdatenode = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Result
|
|
|
|
public int GetResult(int original)
|
|
|
|
{
|
2013-07-11 11:43:49 +00:00
|
|
|
//mxd
|
|
|
|
if(typelist.UseMultiSelection && typelist.SelectedNodes.Count > 1) {
|
|
|
|
List<TreeNode> validNodes = getValidNodes();
|
|
|
|
|
|
|
|
//get a random ThingTypeInfo from valid nodes
|
|
|
|
if(validNodes.Count > 1) {
|
|
|
|
ThingTypeInfo ti = validNodes[General.Random(0, validNodes.Count - 1)].Tag as ThingTypeInfo;
|
|
|
|
return ti.Index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
return typeid.GetResult(original);
|
|
|
|
}
|
|
|
|
|
2013-07-11 11:43:49 +00:00
|
|
|
//mxd
|
|
|
|
private List<TreeNode> getValidNodes() {
|
|
|
|
List<TreeNode> validNodes = new List<TreeNode>();
|
|
|
|
|
|
|
|
foreach(TreeNode n in typelist.SelectedNodes) {
|
|
|
|
if((n.Nodes.Count == 0) && (n.Tag != null) && (n.Tag is ThingTypeInfo))
|
|
|
|
validNodes.Add(n);
|
|
|
|
}
|
|
|
|
|
|
|
|
return validNodes;
|
|
|
|
}
|
|
|
|
|
2009-04-19 18:07:22 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ================== Events
|
|
|
|
|
|
|
|
// List double-clicked
|
|
|
|
private void typelist_DoubleClick(object sender, EventArgs e)
|
|
|
|
{
|
2009-08-19 13:14:55 +00:00
|
|
|
if(typelist.SelectedNode != null)
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
2009-08-19 13:14:55 +00:00
|
|
|
// Node is a child node?
|
|
|
|
TreeNode n = typelist.SelectedNode;
|
|
|
|
if((n.Nodes.Count == 0) && (n.Tag != null) && (n.Tag is ThingTypeInfo))
|
|
|
|
{
|
|
|
|
if((OnTypeDoubleClicked != null) && (typeid.Text.Length > 0)) OnTypeDoubleClicked();
|
|
|
|
}
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Thing type selection changed
|
|
|
|
private void typelist_AfterSelect(object sender, TreeViewEventArgs e)
|
|
|
|
{
|
|
|
|
if(doupdatetextbox)
|
|
|
|
{
|
2013-07-11 11:43:49 +00:00
|
|
|
//mxd. Got a valid multiselection? Well, can't show any useful info about that...
|
|
|
|
if(typelist.UseMultiSelection && typelist.SelectedNodes.Count > 1 && getValidNodes().Count > 1) {
|
|
|
|
doupdatenode = false;
|
2013-07-19 15:30:58 +00:00
|
|
|
if(!string.IsNullOrEmpty(typeid.Text)) // Event will be raised in typeid_OnTextChanged
|
|
|
|
typeid.Text = "";
|
|
|
|
else if(OnTypeChanged != null) // Or raise event here
|
|
|
|
OnTypeChanged(thinginfo);
|
2013-07-11 11:43:49 +00:00
|
|
|
doupdatenode = true;
|
|
|
|
}
|
|
|
|
else if(typelist.SelectedNode != null) //Anything selected?
|
2009-04-19 18:07:22 +00:00
|
|
|
{
|
|
|
|
TreeNode n = typelist.SelectedNode;
|
|
|
|
|
|
|
|
// Node is a child node?
|
|
|
|
if((n.Nodes.Count == 0) && (n.Tag != null) && (n.Tag is ThingTypeInfo))
|
|
|
|
{
|
|
|
|
ThingTypeInfo ti = (n.Tag as ThingTypeInfo);
|
|
|
|
|
|
|
|
// Show info
|
2013-07-11 11:43:49 +00:00
|
|
|
doupdatenode = false;
|
2009-04-19 18:07:22 +00:00
|
|
|
typeid.Text = ti.Index.ToString();
|
2013-07-11 11:43:49 +00:00
|
|
|
doupdatenode = true;
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Thing type index changed
|
|
|
|
private void typeid_TextChanged(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
bool knownthing = false;
|
|
|
|
|
|
|
|
// Any text?
|
|
|
|
if(typeid.Text.Length > 0)
|
|
|
|
{
|
|
|
|
// Get the info
|
2013-07-11 11:43:49 +00:00
|
|
|
int typeindex = typeid.GetResult(0);
|
|
|
|
thinginfo = General.Map.Data.GetThingInfoEx(typeindex);
|
2009-04-19 18:07:22 +00:00
|
|
|
if(thinginfo != null)
|
|
|
|
{
|
|
|
|
knownthing = true;
|
|
|
|
|
|
|
|
// Size
|
|
|
|
sizelabel.Text = (thinginfo.Radius * 2) + " x " + thinginfo.Height;
|
|
|
|
|
|
|
|
// Hangs from ceiling
|
|
|
|
if(thinginfo.Hangs) positionlabel.Text = "Ceiling"; else positionlabel.Text = "Floor";
|
|
|
|
|
|
|
|
// Blocking
|
|
|
|
switch(thinginfo.Blocking)
|
|
|
|
{
|
|
|
|
case ThingTypeInfo.THING_BLOCKING_NONE: blockinglabel.Text = "No"; break;
|
|
|
|
case ThingTypeInfo.THING_BLOCKING_FULL: blockinglabel.Text = "Completely"; break;
|
|
|
|
case ThingTypeInfo.THING_BLOCKING_HEIGHT: blockinglabel.Text = "True-Height"; break;
|
|
|
|
default: blockinglabel.Text = "Unknown"; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(doupdatenode)
|
|
|
|
{
|
|
|
|
doupdatetextbox = false;
|
2013-07-11 11:43:49 +00:00
|
|
|
typelist.ClearSelectedNodes();
|
2009-04-19 18:07:22 +00:00
|
|
|
foreach(TreeNode n in nodes)
|
|
|
|
{
|
|
|
|
// Matching node?
|
|
|
|
if((n.Tag as ThingTypeInfo).Index == typeindex)
|
|
|
|
{
|
|
|
|
// Select this
|
2013-04-04 12:04:52 +00:00
|
|
|
if(typelist.Nodes.Contains(n.Parent)) { //mxd. Tree node may've been removed during filtering
|
|
|
|
n.Parent.Expand();
|
|
|
|
typelist.SelectedNode = n;
|
|
|
|
n.EnsureVisible();
|
|
|
|
}
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
doupdatetextbox = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
thinginfo = null;
|
2013-07-11 11:43:49 +00:00
|
|
|
if(doupdatenode) typelist.ClearSelectedNodes();
|
2009-04-19 18:07:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// No known thing?
|
|
|
|
if(!knownthing)
|
|
|
|
{
|
|
|
|
sizelabel.Text = "-";
|
|
|
|
positionlabel.Text = "-";
|
|
|
|
blockinglabel.Text = "-";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Raise event
|
|
|
|
if(OnTypeChanged != null) OnTypeChanged(thinginfo);
|
|
|
|
}
|
2009-07-09 22:43:39 +00:00
|
|
|
|
|
|
|
// Layout update!
|
|
|
|
private void ThingBrowserControl_Layout(object sender, LayoutEventArgs e)
|
|
|
|
{
|
|
|
|
ThingBrowserControl_SizeChanged(sender, EventArgs.Empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void ThingBrowserControl_Resize(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
ThingBrowserControl_SizeChanged(sender, EventArgs.Empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void ThingBrowserControl_SizeChanged(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
blockingcaption.Left = infopanel.Width / 2;
|
|
|
|
blockinglabel.Left = blockingcaption.Right + blockingcaption.Margin.Right;
|
|
|
|
sizecaption.Left = blockingcaption.Right - sizecaption.Width;
|
|
|
|
sizelabel.Left = sizecaption.Right + sizecaption.Margin.Right;
|
|
|
|
}
|
2013-04-04 12:04:52 +00:00
|
|
|
|
|
|
|
//mxd
|
|
|
|
private void bClear_Click(object sender, EventArgs e) {
|
|
|
|
tbFilter.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
//mxd
|
|
|
|
private void tbFilter_TextChanged(object sender, EventArgs e) {
|
|
|
|
typelist.SuspendLayout();
|
|
|
|
|
|
|
|
if(string.IsNullOrEmpty(tbFilter.Text)) {
|
|
|
|
Setup();
|
|
|
|
typeid_TextChanged(this, EventArgs.Empty);
|
|
|
|
} else {
|
|
|
|
// Go for all predefined categories
|
2013-07-11 11:43:49 +00:00
|
|
|
typelist.ClearSelectedNodes();
|
2013-04-04 12:04:52 +00:00
|
|
|
typelist.Nodes.Clear();
|
|
|
|
|
|
|
|
string match = tbFilter.Text.ToUpperInvariant();
|
|
|
|
foreach(TreeNode node in nodes){
|
|
|
|
if(node.Text.ToUpperInvariant().Contains(match)) {
|
|
|
|
typelist.Nodes.Add(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
doupdatenode = true;
|
|
|
|
doupdatetextbox = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
typelist.ResumeLayout();
|
|
|
|
}
|
2009-04-19 18:07:22 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|