This repository has been archived on 2025-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
RomVault/ROMVault2/rvTree.cs
2014-09-23 12:06:15 -07:00

453 lines
15 KiB
C#

/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using ROMVault2.RvDB;
namespace ROMVault2
{
public partial class RvTree : UserControl
{
public event MouseEventHandler RvSelected;
private RvDir _lTree;
private RvDir _lSelected;
public RvTree()
{
InitializeComponent();
}
#region "Setup"
private int _yPos;
public void Setup(ref RvDir dirTree)
{
_lSelected = null;
_lTree = dirTree;
SetupInt();
}
private void SetupInt()
{
_yPos = 0;
int treeCount = _lTree.ChildCount;
if (treeCount >= 1)
{
for (int i = 0; i < treeCount - 1; i++)
SetupTree((RvDir)_lTree.Child(i), "├");
SetupTree((RvDir)_lTree.Child(treeCount - 1), "└");
}
AutoScrollMinSize = new Size(500, _yPos);
Refresh();
}
private void SetupTree(RvDir pTree, string pTreeBranches)
{
int nodeDepth = pTreeBranches.Length - 1;
pTree.Tree.TreeBranches = pTreeBranches;
pTree.Tree.RTree = new Rectangle(0, _yPos - 8, nodeDepth * 18, 16);
pTree.Tree.RExpand = new Rectangle(5 + nodeDepth * 18, _yPos + 4, 9, 9);
pTree.Tree.RChecked = new Rectangle(20 + nodeDepth * 18, _yPos + 2, 13, 13);
pTree.Tree.RIcon = new Rectangle(35 + nodeDepth * 18, _yPos, 16, 16);
pTree.Tree.RText = new Rectangle(51 + nodeDepth * 18, _yPos, 500, 16);
pTreeBranches = pTreeBranches.Replace("├", "│");
pTreeBranches = pTreeBranches.Replace("└", " ");
_yPos = _yPos + 16;
bool found = false;
int last = 0;
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase t = pTree.Child(i);
if (t is RvDir)
if (((RvDir)t).Tree != null)
{
found = true;
if (pTree.Tree.TreeExpanded)
last = i;
}
}
if (!found)
pTree.Tree.RExpand = new Rectangle(0, 0, 0, 0);
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase t = pTree.Child(i);
if (t is RvDir)
if (((RvDir)t).Tree != null)
{
if (pTree.Tree.TreeExpanded)
{
if (i != last)
SetupTree((RvDir)pTree.Child(i), pTreeBranches + "├");
else
SetupTree((RvDir)pTree.Child(i), pTreeBranches + "└");
}
}
}
}
#endregion
#region "Paint"
private int _hScroll;
private int _vScroll;
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
_hScroll = HorizontalScroll.Value;
_vScroll = VerticalScroll.Value;
Rectangle t = new Rectangle(e.ClipRectangle.Left + _hScroll, e.ClipRectangle.Top + _vScroll, e.ClipRectangle.Width, e.ClipRectangle.Height);
g.FillRectangle(Brushes.White, e.ClipRectangle);
if (_lTree != null)
for (int i = 0; i < _lTree.ChildCount; i++)
{
RvBase tBase = _lTree.Child(i);
if (tBase is RvDir)
{
RvDir tDir = (RvDir)tBase;
if (tDir.Tree != null)
PaintTree(tDir, g, t);
}
}
}
private void PaintTree(RvDir pTree, Graphics g, Rectangle t)
{
int y = pTree.Tree.RTree.Top - _vScroll;
if (pTree.Tree.RTree.IntersectsWith(t))
{
Pen p = new Pen(Brushes.Gray, 1) { DashStyle = DashStyle.Dot };
string lTree = pTree.Tree.TreeBranches;
for (int j = 0; j < lTree.Length; j++)
{
int x = j * 18 - _hScroll;
string cTree = lTree.Substring(j, 1);
switch (cTree)
{
case "│":
g.DrawLine(p, x + 9, y, x + 9, y + 16);
break;
case "├":
case "└":
g.DrawLine(p, x + 9, y, x + 9, y + 16);
g.DrawLine(p, x + 9, y + 16, x + 27, y + 16);
break;
}
}
}
if (!pTree.Tree.RExpand.IsEmpty)
if (pTree.Tree.RExpand.IntersectsWith(t))
{
g.DrawImage(pTree.Tree.TreeExpanded ? rvImages.ExpandBoxMinus : rvImages.ExpandBoxPlus, RSub(pTree.Tree.RExpand, _hScroll, _vScroll));
}
if (pTree.Tree.RChecked.IntersectsWith(t))
{
switch (pTree.Tree.Checked)
{
case RvTreeRow.TreeSelect.Disabled:
g.DrawImage(rvImages.TickBoxDisabled, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
break;
case RvTreeRow.TreeSelect.UnSelected:
g.DrawImage(rvImages.TickBoxUnTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
break;
case RvTreeRow.TreeSelect.Selected:
g.DrawImage(rvImages.TickBoxTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
break;
}
}
if (pTree.Tree.RIcon.IntersectsWith(t))
{
int icon = 2;
if (pTree.DirStatus.HasInToSort())
{
icon = 4;
}
else if (!pTree.DirStatus.HasCorrect())
{
icon = 1;
}
else if (!pTree.DirStatus.HasMissing())
{
icon = 3;
}
Bitmap bm;
if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree
bm = rvImages.GetBitmap("DirectoryTree" + icon);
else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's
bm = rvImages.GetBitmap("Tree" + icon);
else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT
bm = rvImages.GetBitmap("Tree" + icon);
else
{
ReportError.SendAndShow("Unknown Tree settings in DisplayTree.");
bm = null;
}
if (bm != null)
{
g.DrawImage(bm, RSub(pTree.Tree.RIcon, _hScroll, _vScroll));
}
}
Rectangle recBackGround = new Rectangle(pTree.Tree.RText.X, pTree.Tree.RText.Y, Width - pTree.Tree.RText.X + _hScroll, pTree.Tree.RText.Height);
if (recBackGround.IntersectsWith(t))
{
string thistxt;
if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree
thistxt = pTree.Name;
else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's
thistxt = pTree.Name + ": " + pTree.DirDat(0).GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
// pTree.Parent.DirDatCount>1: This should probably be a test like parent contains Dat
else if (pTree.Dat != null && pTree.Dat.AutoAddDirectory && pTree.Parent.DirDatCount > 1)
thistxt = pTree.Name + ": " + pTree.Dat.GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT
thistxt = pTree.Name + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
else
{
ReportError.SendAndShow("Unknown Tree settings in DisplayTree.");
thistxt = "";
}
if (_lSelected != null && pTree.TreeFullName == _lSelected.TreeFullName)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(51, 153, 255)), RSub(recBackGround, _hScroll, _vScroll));
g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.White, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll);
}
else
{
g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.Black, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll);
}
}
if (pTree.Tree.TreeExpanded)
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase tBase = pTree.Child(i);
if (tBase is RvDir)
{
RvDir tDir = (RvDir)tBase;
if (tDir.Tree != null)
PaintTree(tDir, g, t);
}
}
}
private static Rectangle RSub(Rectangle r, int h, int v)
{
Rectangle ret = new Rectangle(r.Left - h, r.Top - v, r.Width, r.Height);
return ret;
}
#endregion
#region"Mouse Events"
private bool _mousehit;
protected override void OnMouseDown(MouseEventArgs mevent)
{
int x = mevent.X + HorizontalScroll.Value;
int y = mevent.Y + VerticalScroll.Value;
if (_lTree != null)
for (int i = 0; i < _lTree.ChildCount; i++)
{
RvDir tDir = (RvDir)_lTree.Child(i);
if (tDir.Tree != null)
if (CheckMouseDown(tDir, x, y, mevent))
break;
}
if (!_mousehit) return;
SetupInt();
base.OnMouseDown(mevent);
}
public void SetSelected(RvDir selected)
{
bool found = false;
RvDir t = selected;
while (t != null)
{
if (t.Tree != null)
{
if (!found)
{
_lSelected = t;
found = true;
}
else
t.Tree.TreeExpanded = true;
}
t = t.Parent;
}
SetupInt();
}
public RvDir GetSelected()
{
return _lSelected;
}
private bool CheckMouseDown(RvDir pTree, int x, int y, MouseEventArgs mevent)
{
if (pTree.Tree.RChecked.Contains(x, y))
{
if (pTree.Tree.Checked == RvTreeRow.TreeSelect.Disabled)
return true;
_mousehit = true;
SetChecked(pTree, pTree.Tree.Checked == RvTreeRow.TreeSelect.Selected ? RvTreeRow.TreeSelect.UnSelected : RvTreeRow.TreeSelect.Selected);
return true;
}
if (pTree.Tree.RExpand.Contains(x, y))
{
_mousehit = true;
SetExpanded(pTree, mevent.Button == MouseButtons.Right);
return true;
}
if (pTree.Tree.RText.Contains(x, y))
{
_mousehit = true;
if (RvSelected != null)
RvSelected(pTree, mevent);
_lSelected = pTree;
return true;
}
if (pTree.Tree.TreeExpanded)
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase rBase = pTree.Child(i);
if (rBase is RvDir)
{
RvDir rDir = (RvDir)rBase;
if (rDir.Tree != null)
if (CheckMouseDown(rDir, x, y, mevent))
return true;
}
}
return false;
}
private static void SetChecked(RvDir pTree, RvTreeRow.TreeSelect nSelection)
{
pTree.Tree.Checked = nSelection;
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase b = pTree.Child(i);
if (b is RvDir)
{
RvDir d = (RvDir)b;
if (d.Tree != null)
{
SetChecked(d, nSelection);
}
}
}
}
private static void SetExpanded(RvDir pTree, bool rightClick)
{
if (!rightClick)
{
pTree.Tree.TreeExpanded = !pTree.Tree.TreeExpanded;
return;
}
// Find the value of the first child node.
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase b = pTree.Child(i);
if (b is RvDir)
{
RvDir d = (RvDir)b;
if (d.Tree != null)
{
//Recusivly Set All Child Nodes to this value
SetExpandedRecurse(pTree, !d.Tree.TreeExpanded);
break;
}
}
}
}
private static void SetExpandedRecurse(RvDir pTree, bool expanded)
{
for (int i = 0; i < pTree.ChildCount; i++)
{
RvBase b = pTree.Child(i);
if (b is RvDir)
{
RvDir d = (RvDir)b;
if (d.Tree != null)
{
d.Tree.TreeExpanded = expanded;
SetExpandedRecurse(d, expanded);
}
}
}
}
#endregion
public RvBase Selected
{
get
{
return _lSelected;
}
}
}
}