214 lines
7.8 KiB
C#
214 lines
7.8 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
|
|
namespace DevComponents.Tree.Display
|
|
{
|
|
/// <summary>
|
|
/// Represents professional rendered which provides extensive rendering above and beyond the NodeSystemRenderer.
|
|
/// </summary>
|
|
public class NodeProfessionalRenderer : NodeSystemRenderer
|
|
{
|
|
#region Private Variables
|
|
private NodeProfessionalColorTable m_ColorTable=new NodeProfessionalColorTable();
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Gets or sets the color table used by renderer.
|
|
/// </summary>
|
|
public NodeProfessionalColorTable ColorTable
|
|
{
|
|
get { return m_ColorTable;}
|
|
set
|
|
{
|
|
m_ColorTable = value;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="e">Information provided for rendering.</param>
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Paints background of the node.
|
|
/// </summary>
|
|
/// <param name="e">Context information.</param>
|
|
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;
|
|
}
|
|
|
|
}
|
|
}
|