using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace DevComponents.Tree.Display
{
///
/// Represents professional rendered which provides extensive rendering above and beyond the NodeSystemRenderer.
///
public class NodeProfessionalRenderer : NodeSystemRenderer
{
#region Private Variables
private NodeProfessionalColorTable m_ColorTable=new NodeProfessionalColorTable();
#endregion
///
/// Gets or sets the color table used by renderer.
///
public NodeProfessionalColorTable ColorTable
{
get { return m_ColorTable;}
set
{
m_ColorTable = value;
}
}
///
/// Draws node background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeBackground method so events can occur.
///
/// Information provided for rendering.
public override void DrawNodeBackground(NodeRendererEventArgs e)
{
ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(e.Style,e.Graphics,DisplayHelp.GetDrawRectangle(e.NodeBounds));
PaintBackground(e);
ElementStyleDisplay.PaintBackgroundImage(di);
ElementStyleDisplay.PaintBorder(di);
// Let events occur
OnRenderNodeBackground(e);
}
private void PaintBackgroundPart(Graphics g, Rectangle bounds, GraphicsPath path, Color color1, Color color2, eGradientType gradientType, int gradientAngle)
{
if(color2.IsEmpty)
{
if(!color1.IsEmpty)
{
using(SolidBrush brush=new SolidBrush(color1))
g.FillPath(brush,path);
}
}
else if(!m_ColorTable.NodeTopGradientBegin.IsEmpty)
{
if (gradientType == eGradientType.Linear)
{
Rectangle rb = bounds;
rb.X--;
rb.Height++;
rb.Width += 2;
using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, color1, color2, gradientAngle))
{
g.FillPath(brush, path);
}
}
else if (gradientType == eGradientType.Radial)
{
int d = (int)Math.Sqrt(bounds.Width * bounds.Width + bounds.Height * bounds.Height);
GraphicsPath fillPath = new GraphicsPath();
fillPath.AddEllipse(bounds.X - (d - bounds.Width), bounds.Y - (d - bounds.Height) / 2, d, d);
using (PathGradientBrush brush = new PathGradientBrush(fillPath))
{
brush.CenterColor = color1;
brush.SurroundColors = new Color[] { color2 };
g.FillPath(brush, path);
}
fillPath.Dispose();
}
}
}
///
/// Paints background of the node.
///
/// Context information.
protected virtual void PaintBackground(NodeRendererEventArgs e)
{
Graphics g = e.Graphics;
bool mouseOver = e.Node.IsMouseOver;
Region oldClip = g.Clip;
Rectangle clipRect=e.NodeBounds;
clipRect.Width--;
clipRect.Height--;
g.SetClip(clipRect, CombineMode.Replace);
// Prepare colors
NodeColors colors=new NodeColors();
colors.NodeTopGradientBegin = m_ColorTable.NodeTopGradientBegin;
colors.NodeTopGradientMiddle = m_ColorTable.NodeTopGradientMiddle;
colors.NodeTopGradientEnd = m_ColorTable.NodeTopGradientEnd;
colors.NodeTopGradientType = m_ColorTable.NodeTopGradientType;
colors.NodeTopGradientAngle = m_ColorTable.NodeTopGradientAngle;
colors.NodeBottomGradientBegin = m_ColorTable.NodeBottomGradientBegin;
colors.NodeBottomGradientMiddle = m_ColorTable.NodeBottomGradientMiddle;
colors.NodeBottomGradientEnd = m_ColorTable.NodeBottomGradientEnd;
colors.NodeBottomGradientType = m_ColorTable.NodeBottomGradientType;
colors.NodeBottomGradientAngle = m_ColorTable.NodeBottomGradientAngle;
if(mouseOver)
{
colors.NodeTopGradientBegin = m_ColorTable.NodeMouseOverTopGradientBegin;
colors.NodeTopGradientMiddle = m_ColorTable.NodeMouseOverTopGradientMiddle;
colors.NodeTopGradientEnd = m_ColorTable.NodeMouseOverTopGradientEnd;
colors.NodeTopGradientType = m_ColorTable.NodeMouseOverTopGradientType;
colors.NodeTopGradientAngle = m_ColorTable.NodeMouseOverTopGradientAngle;
colors.NodeBottomGradientBegin = m_ColorTable.NodeMouseOverBottomGradientBegin;
colors.NodeBottomGradientMiddle = m_ColorTable.NodeMouseOverBottomGradientMiddle;
colors.NodeBottomGradientEnd = m_ColorTable.NodeMouseOverBottomGradientEnd;
colors.NodeBottomGradientType = m_ColorTable.NodeMouseOverBottomGradientType;
colors.NodeBottomGradientAngle = m_ColorTable.NodeMouseOverBottomGradientAngle;
}
// Paint Background, Top Part
Rectangle bounds=DisplayHelp.GetDrawRectangle(ElementStyleDisplay.GetBackgroundRectangle(e.Style,e.NodeBounds));
GraphicsPath path;
if (g.SmoothingMode == SmoothingMode.AntiAlias)
{
Rectangle r = bounds;
r.Width--;
path = ElementStyleDisplay.GetBackgroundPath(e.Style, r, eStyleBackgroundPathPart.TopHalf);
}
else
path = ElementStyleDisplay.GetBackgroundPath(e.Style, bounds, eStyleBackgroundPathPart.TopHalf);
path.CloseAllFigures();
Rectangle backRect = bounds;
backRect.Height = backRect.Height/2;
PaintBackgroundPart(g, backRect, path, colors.NodeTopGradientBegin, colors.NodeTopGradientEnd,
colors.NodeTopGradientType, colors.NodeTopGradientAngle);
Rectangle ellipse = new Rectangle(bounds.X, bounds.Y - bounds.Height / 2, bounds.Width, bounds.Height);
GraphicsPath pathFill=new GraphicsPath();
pathFill.AddEllipse(ellipse);
PathGradientBrush pathBrush = new PathGradientBrush(pathFill);
pathBrush.CenterColor = colors.NodeTopGradientMiddle;
pathBrush.SurroundColors = new Color[] { Color.Transparent };
pathBrush.CenterPoint = new PointF(ellipse.X + ellipse.Width / 2, bounds.Y);
Blend blend = new Blend();
blend.Factors = new float[] { 0f, .8f, 1f };
blend.Positions = new float[] { .0f, .8f, 1f };
pathBrush.Blend = blend;
pathFill.Dispose();
g.FillPath(pathBrush, path);
pathBrush.Dispose();
path.Dispose();
// Bottom Part
if (g.SmoothingMode == SmoothingMode.AntiAlias)
{
Rectangle r = bounds;
r.Width--;
path = ElementStyleDisplay.GetBackgroundPath(e.Style, r, eStyleBackgroundPathPart.BottomHalf);
}
else
path = ElementStyleDisplay.GetBackgroundPath(e.Style, bounds, eStyleBackgroundPathPart.BottomHalf);
path.CloseAllFigures();
backRect.Y += backRect.Height;
PaintBackgroundPart(g, backRect, path, colors.NodeBottomGradientBegin, colors.NodeBottomGradientEnd,
colors.NodeBottomGradientType, colors.NodeBottomGradientAngle);
ellipse = new Rectangle(bounds.X, bounds.Y + bounds.Height / 2 - 2, bounds.Width, bounds.Height + 4);
pathFill=new GraphicsPath();
pathFill.AddEllipse(ellipse);
pathBrush = new PathGradientBrush(pathFill);
pathBrush.CenterColor = colors.NodeBottomGradientMiddle;
pathBrush.SurroundColors = new Color[] { Color.Transparent };
pathBrush.CenterPoint = new PointF(ellipse.X + ellipse.Width / 2, bounds.Bottom);
blend = new Blend();
blend.Factors = new float[] { 0f, .5f, 1f };
blend.Positions = new float[] { .0f, .4f, 1f };
pathBrush.Blend = blend;
//path.Dispose();
g.FillPath(pathBrush, path);
pathBrush.Dispose();
pathFill.Dispose();
path.Dispose();
if (oldClip != null)
g.Clip = oldClip;
else
g.ResetClip();
}
private class NodeColors
{
public Color NodeTopGradientBegin;
public Color NodeTopGradientMiddle;
public Color NodeTopGradientEnd;
public eGradientType NodeTopGradientType=eGradientType.Linear;
public int NodeTopGradientAngle=90;
public Color NodeBottomGradientBegin;
public Color NodeBottomGradientMiddle;
public Color NodeBottomGradientEnd;
public eGradientType NodeBottomGradientType=eGradientType.Linear;
public int NodeBottomGradientAngle=90;
}
}
}