private static IDisposable DrawBackGlassFade(RectangleF drawRect,
RectangleF outerRect,
Color color1,
Color color2,
Color glassColor1,
Color glassColor2,
VisualOrientation orientation,
Graphics g,
IDisposable memento)
{
// Cannot draw a zero length rectangle
if ((drawRect.Width > 0) && (drawRect.Height > 0) &&
(outerRect.Width > 0) && (outerRect.Height > 0))
{
bool generate = true;
MementoBackGlassFade cache;
// Access a cache instance and decide if cache resources need generating
if ((memento == null) || !(memento is MementoBackGlassFade))
{
if (memento != null)
memento.Dispose();
cache = new MementoBackGlassFade(drawRect, outerRect, color1, color2,
glassColor1, glassColor2, orientation);
memento = cache;
}
else
{
cache = (MementoBackGlassFade)memento;
generate = !cache.UseCachedValues(drawRect, outerRect, color1, color2,
glassColor1, glassColor2, orientation);
}
// Do we need to generate the contents of the cache?
if (generate)
{
// Dispose of existing values
cache.Dispose();
// Create gradient rect from the drawing rect
RectangleF gradientRect = new RectangleF(drawRect.X - 1, drawRect.Y - 1, drawRect.Width + 2, drawRect.Height + 2);
// Cannot draw a zero sized rectangle
if ((gradientRect.Width > 0) && (gradientRect.Height > 0))
{
// Draw a gradient from first to second over the length, but use the
// first color for the first 33% of distance and fade over the rest
cache.mainBrush = new LinearGradientBrush(gradientRect, color1, color2, AngleFromOrientation(orientation));
cache.mainBrush.Blend = _glassFadeBlend;
}
float glassLength;
// Glass covers 33% of the orienatated length
if (VerticalOrientation(orientation))
glassLength = (int)(outerRect.Height * 0.33f) + outerRect.Y - drawRect.Y;
else
glassLength = (int)(outerRect.Width * 0.33f) + outerRect.X - drawRect.X;
RectangleF glassRect;
RectangleF mainRect;
// Create rectangles that cover the glass and main area
switch (orientation)
{
case VisualOrientation.Left:
glassRect = new RectangleF(drawRect.X, drawRect.Y, glassLength, drawRect.Height);
break;
case VisualOrientation.Right:
mainRect = new RectangleF(drawRect.X, drawRect.Y, drawRect.Width - glassLength, drawRect.Height);
glassRect = new RectangleF(mainRect.Right, drawRect.Y, glassLength, drawRect.Height);
break;
case VisualOrientation.Top:
default:
glassRect = new RectangleF(drawRect.X, drawRect.Y, drawRect.Width, glassLength);
break;
case VisualOrientation.Bottom:
mainRect = new RectangleF(drawRect.X, drawRect.Y, drawRect.Width, drawRect.Height - glassLength);
glassRect = new RectangleF(drawRect.X, mainRect.Bottom, drawRect.Width, glassLength);
break;
}
// Create gradient rectangles
RectangleF glassGradientRect = new RectangleF(glassRect.X - 1, glassRect.Y - 1, glassRect.Width + 2, glassRect.Height + 2);
// Cannot draw a zero sized rectangle
if ((glassRect.Width > 0) && (glassRect.Height > 0) &&
(glassGradientRect.Width > 0) && (glassGradientRect.Height > 0))
{
// Use semi-transparent white colors to create the glass effect
cache.topBrush = new LinearGradientBrush(glassGradientRect, glassColor1, glassColor2, AngleFromOrientation(orientation));
cache.glassRect = glassRect;
}
}
if (cache.mainBrush != null)
g.FillRectangle(cache.mainBrush, drawRect);
if (cache.topBrush != null)
g.FillRectangle(cache.topBrush, cache.glassRect);
}
return memento;
}