internal void CalcAnimationHeights()
{
// Windows XP uses a Bezier curve to calculate the height of
// an Expando during a fade animation, so here we precalculate
// the height of the "client area" for each frame.
//
// I can't describe what's happening better than David Nissimoff,
// so here's David's description of what goes on:
//
// "The only thing that I've noticed is that the animation routine
// doesn't completely simulate the one used in Windows. After 2 days
// of endless tests I have finally discovered what should've been written
// to accurately simulate Windows XP behaviour.
// I first created a simple application in VB that would copy an
// area of the screen (set to one of the Windows' expandos) every time
// it changed. Having that information, analyzing every frame of the
// animation I could see that it would always be formed of 23 steps.
// Once having all of the animation, frame by frame, I could see
// that the expando's height obeyed to a bézier curve. For testing
// purposes, I have created an application that draws the bézier curve
// on top of the frames put side by side, and it matches 100%.
// The height of the expando in each step would be the vertical
// position of the bézier in the horizontal position(i.e. the step).
// A bézier should be drawn into a Graphics object, with x1 set to
// 0 (initial step = 0) and y1 to the initial height of the expando to
// be animated. The first control point (x2,y2) is defined by:
// x2 = (numAnimationSteps / 4) * 3
// y2 = (HeightVariation / 4) * 3
// The second control point (x3,y3) is defined as follows:
// x3 = numAnimationSteps / 4
// y3 = HeightVariation / 4
// The end point (x3,y3) would be:
// x4 = 22 --> 23 steps = 0 to 22
// y4 = FinalAnimationHeight
// Then, to get the height of the expando on any desired step, you
// should call the Bitmap used to create the Graphics and look pixel by
// pixel in the column of the step number until you find the curve."
//
// I hope that helps ;)
using (Bitmap bitmap = new Bitmap(this.fadeHeights.Length, this.ExpandedHeight - this.HeaderHeight))
{
// draw the bezier curve
using (Graphics g = Graphics.FromImage(bitmap))
{
g.Clear(Color.White);
g.DrawBezier(new Pen(Color.Black),
0,
bitmap.Height - 1,
bitmap.Width / 4 * 3,
bitmap.Height / 4 * 3,
bitmap.Width / 4,
bitmap.Height / 4,
bitmap.Width - 1,
0);
}
// extract heights
for (int i=0; i<bitmap.Width; i++)
{
int j = bitmap.Height - 1;
for (; j>0; j--)
{
if (bitmap.GetPixel(i, j).R == 0)
{
break;
}
}
this.fadeHeights[i] = j;
}
}
}