I've been working on a program that visually outputs the contents of a binary tree (represented in turn by classes that I wrote myself). The last feature I want to include in this program is an animation of the postorder, inorder, and preorder construction of the tree.
This has proven much more challenging than I thought. Here's the original Draw Method:
private void DrawNode(int x, int y, BinaryTreeNode<T> node, int nodeLevel, int maxDepth, int connectX = -1, int connectY = -1, )
{
//calculate distance between the node's children
int distance = CalculateDistance(nodeLevel, maxDepth);
//draw the node at the specified coordinate
node.Draw(x, y, this.device);
if (node.Left != null)
{
DrawNode(x - distance / 2, y + 50, node.Left, nodeLevel + 1, maxDepth, x, y, node);
}
if (node.Right != null)
{
DrawNode(x + distance / 2, y + 50, node.Right, nodeLevel + 1, maxDepth, x, y, node);
}
//connect the node to its parent
if ((connectX != -1) && (connectY != -1))
{
node.Connect(connectX, connectY, device);
}
this.display.Image = surface;
}
My original idea was to simply put Thread.Sleep(1000) inside each of the first two if clauses - all I really needed to do was pause the execution of the program for 1 second before each drawing of a node.
I realized that the Sleep method was blocking the execution of the drawing code, so I gave up on that method.. I then tried to use Timers, but found it impossibly difficult when dealing with the tree.
My goal is to simply find a way to pause program execution without disrupting the GUI's responsiveness and without overly complicating the code..
Any help would be appreciated :).
Edit: Some potentially relevant information: The program runs on Winforms, all graphics are handled via GDI+. If you need any other information, just ask :)
Edit: For SLaks,
//draw the node's children
if (drawChildren)
{
if (node.Left != null)
{
if (this.timer2.Enabled)
{
this.timer2.Stop();
}
if (!this.timer1.Enabled)
{
this.timer1.Start();
}
this.count1++;
this.timer1.Tick += (object source, EventArgs e) =>
{
this.count1--;
DrawNode(x - distance / 2, y + 50, node.Left, nodeLevel + 1, maxDepth, x, y, node);
if (this.count1 == 0)
{
this.timer1.Stop();
}
};
}
else
{
this.timer1.Stop();
this.timer2.Start();
}
if (node.Right != null)
{
this.count2++;
this.timer2.Tick += (object source, EventArgs e) =>
{
this.count2--;
DrawNode(x + distance / 2, y + 50, node.Right, nodeLevel + 1, maxDepth, x, y, node);
if (this.count2 == 0)
{
this.timer2.Stop();
}
};
}
}