private static IDisposable DrawBackGlassRadial(RectangleF drawRect,
Color color1,
Color color2,
Color glassColor1,
Color glassColor2,
float factorX,
float factorY,
VisualOrientation orientation,
Graphics g,
float glassPercent,
IDisposable memento)
{
MementoDouble cache;
if ((memento == null) || !(memento is MementoDouble))
{
if (memento != null)
memento.Dispose();
cache = new MementoDouble();
memento = cache;
}
else
{
cache = (MementoDouble)memento;
}
// Draw the gradient effect background
RectangleF glassRect = DrawBackGlassBasic(drawRect, color1, color2,
glassColor1, glassColor2,
factorX, factorY,
orientation, g,
glassPercent,
ref cache.first);
bool generate = true;
MementoBackGlassRadial cacheThis;
// Access a cache instance and decide if cache resources need generating
if ((cache.second == null) || !(cache.second is MementoBackGlassRadial))
{
if (cache.second != null)
cache.second.Dispose();
cacheThis = new MementoBackGlassRadial(drawRect, color1, color2, factorX, factorY, orientation);
cache.second = cacheThis;
}
else
{
cacheThis = (MementoBackGlassRadial)cache.second;
generate = !cacheThis.UseCachedValues(drawRect, color1, color2, factorX, factorY, orientation);
}
// Do we need to generate the contents of the cache?
if (generate)
{
// Dispose of existing values
cacheThis.Dispose();
// Find the bottom area rectangle
RectangleF mainRect;
switch (orientation)
{
case VisualOrientation.Right:
mainRect = new RectangleF(drawRect.X, drawRect.Y, drawRect.Width - glassRect.Width - 1, drawRect.Height);
break;
case VisualOrientation.Left:
mainRect = new RectangleF(glassRect.Right + 1, drawRect.Y, drawRect.Width - glassRect.Width - 1, drawRect.Height);
break;
case VisualOrientation.Bottom:
mainRect = new RectangleF(drawRect.X, drawRect.Y, drawRect.Width, drawRect.Height - glassRect.Height - 1);
break;
case VisualOrientation.Top:
default:
mainRect = new RectangleF(drawRect.X, glassRect.Bottom + 1, drawRect.Width, drawRect.Height - glassRect.Height - 1);
break;
}
RectangleF doubleRect;
// Find the box that encloses the ellipse (ellipses is sized using the factorX, factorY)
if (VerticalOrientation(orientation))
{
float mainRectWidth = (mainRect.Width * factorX);
float mainRectWidthOffset = (mainRectWidth - mainRect.Width) / 2;
float mainRectHeight = (mainRect.Height * factorY);
float mainRectHeightOffset;
// Find orientation specific ellsipe rectangle
if (orientation == VisualOrientation.Top)
mainRectHeightOffset = (mainRectHeight - mainRect.Height) / 2;
else
mainRectHeightOffset = (mainRectHeight + (mainRectHeight - mainRect.Height) / 2);
doubleRect = new RectangleF(mainRect.X - mainRectWidthOffset,
mainRect.Y - mainRectHeightOffset,
mainRectWidth, mainRectHeight * 2);
}
else
{
float mainRectHeight = (mainRect.Height * factorX);
float mainRectHeightOffset = (mainRectHeight - mainRect.Height) / 2;
float mainRectWidth = (mainRect.Width * factorY);
float mainRectWidthOffset;
// Find orientation specific ellsipe rectangle
if (orientation == VisualOrientation.Left)
mainRectWidthOffset = (mainRectWidth - mainRect.Width) / 2;
else
mainRectWidthOffset = (mainRectWidth + (mainRectWidth - mainRect.Width) / 2);
doubleRect = new RectangleF(mainRect.X - mainRectWidthOffset,
mainRect.Y - mainRectHeightOffset,
mainRectWidth * 2, mainRectHeight);
}
// Cannot draw a path that contains a zero sized element
if ((doubleRect.Width > 0) && (doubleRect.Height > 0))
{
// We use a path to create an ellipse for the light effect in the bottom of the area
cacheThis.path = new GraphicsPath();
cacheThis.path.AddEllipse(doubleRect);
// Create a brush from the path
cacheThis.bottomBrush = new PathGradientBrush(cacheThis.path);
cacheThis.bottomBrush.CenterColor = color2;
cacheThis.bottomBrush.CenterPoint = new PointF(doubleRect.X + (doubleRect.Width / 2), doubleRect.Y + (doubleRect.Height / 2));
cacheThis.bottomBrush.SurroundColors = new Color[] { color1 };
cacheThis.mainRect = mainRect;
}
}
if (cacheThis.bottomBrush != null)
g.FillRectangle(cacheThis.bottomBrush, cacheThis.mainRect);
return memento;
}