using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using FastReport.Utils;
namespace FastReport.Gauge.Simple
{
///
/// Represents a simple scale.
///
#if !DEBUG
[DesignTimeVisible(false)]
#endif
public class SimpleScale : GaugeScale
{
#region Fields
private float left;
private float top;
private float height;
private float width;
private int majorTicksNum;
private SimpleSubScale firstSubScale;
private SimpleSubScale secondSubScale;
private float pointerWidthOffset;
private float pointerHeightOffset;
#endregion // Fields
#region Properties
///
/// Gets or sets the first subscale (top or left).
///
[Browsable(true)]
public virtual SimpleSubScale FirstSubScale
{
get { return firstSubScale; }
set { firstSubScale = value; }
}
///
/// Gets or sets the second subscale (right or bottom).
///
[Browsable(true)]
public virtual SimpleSubScale SecondSubScale
{
get { return secondSubScale; }
set { secondSubScale = value; }
}
#endregion // Properties
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The parent gauge object.
public SimpleScale(GaugeObject parent) : base(parent)
{
MajorTicks = new ScaleTicks(10, 2, Color.Black);
MinorTicks = new ScaleTicks(6, 1, Color.Black);
majorTicksNum = 6;
firstSubScale = new SimpleSubScale();
secondSubScale = new SimpleSubScale();
}
#endregion // Constructors
#region Private Methods
private void DrawMajorTicksHorz(FRPaintEventArgs e)
{
IGraphics g = e.Graphics;
Pen pen = e.Cache.GetPen(MajorTicks.Color, MajorTicks.Width * e.ScaleX, DashStyle.Solid);
Brush brush = TextFill.CreateBrush(new RectangleF(Parent.AbsLeft, Parent.AbsTop, Parent.Width, Parent.Height), e.ScaleX, e.ScaleY);
pointerHeightOffset = (Parent.Pointer as SimplePointer).Height / 2 + Parent.Pointer.BorderWidth * 2 * e.ScaleY;
float x = left;
float y1 = top;
float y2 = top + height / 2 - pointerHeightOffset;
float y3 = top + height / 2 + pointerHeightOffset;
float y4 = top + height;
float step = width / (majorTicksNum - 1);
int textStep = (int)((Parent.Maximum - Parent.Minimum) / (majorTicksNum - 1));
Font font = e.Cache.GetFont(Font.FontFamily, Parent.IsPrinting ? Font.Size : Font.Size * e.ScaleX * 96f / DrawUtils.ScreenDpi, Font.Style);
string text = Parent.Minimum.ToString();
if (firstSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum; i++)
{
g.DrawLine(pen, x, y1, x, y2);
if (firstSubScale.ShowCaption)
{
SizeF strSize = g.MeasureString(text, Font);
g.DrawString(text, font, brush, x - strSize.Width / 2 * e.ScaleX / (DrawUtils.ScreenDpi / 96f), y1 - 0.4f * Units.Centimeters * e.ScaleY);
text = Convert.ToString(textStep * (i + 1) + Parent.Minimum);
}
x += step;
}
}
x = left;
text = Parent.Minimum.ToString();
if (secondSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum; i++)
{
g.DrawLine(pen, x, y3, x, y4);
if (secondSubScale.ShowCaption)
{
SizeF strSize = g.MeasureString(text, Font);
g.DrawString(text, font, brush, x - strSize.Width / 2 * e.ScaleX / (DrawUtils.ScreenDpi / 96f), y4 + 0.08f * Units.Centimeters * e.ScaleY);
text = Convert.ToString(textStep * (i + 1) + Parent.Minimum);
}
x += step;
}
}
brush.Dispose();
}
private void DrawMinorTicksHorz(FRPaintEventArgs e)
{
IGraphics g = e.Graphics;
Pen pen = e.Cache.GetPen(MinorTicks.Color, MinorTicks.Width * e.ScaleX, DashStyle.Solid);
pointerHeightOffset = (Parent.Pointer as SimplePointer).Height / 2 + Parent.Pointer.BorderWidth * 2 * e.ScaleY;
float x = left;
float y1 = top + height * 0.15f;
float y2 = top + height / 2 - pointerHeightOffset;
float y3 = top + height / 2 + pointerHeightOffset;
float y4 = top + height - height * 0.15f;
float step = width / (majorTicksNum - 1) / 4;
if (firstSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum - 1; i++)
{
x += step;
for (int j = 0; j < 3; j++)
{
g.DrawLine(pen, x, y1, x, y2);
x += step;
}
}
}
x = left;
if (secondSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum - 1; i++)
{
x += step;
for (int j = 0; j < 3; j++)
{
g.DrawLine(pen, x, y3, x, y4);
x += step;
}
}
}
}
private void DrawMajorTicksVert(FRPaintEventArgs e)
{
IGraphics g = e.Graphics;
Pen pen = e.Cache.GetPen(MajorTicks.Color, MajorTicks.Width * e.ScaleY, DashStyle.Solid);
Brush brush = TextFill.CreateBrush(new RectangleF(Parent.AbsLeft * e.ScaleX, Parent.AbsTop * e.ScaleY,
Parent.Width * e.ScaleX, Parent.Height * e.ScaleY), e.ScaleX, e.ScaleY);
pointerWidthOffset = (Parent.Pointer as SimplePointer).Width / 2 + Parent.Pointer.BorderWidth * 2 * e.ScaleX;
float y = top + height;
float x1 = left;
float x2 = left + width / 2 - pointerWidthOffset;
float x3 = left + width / 2 + pointerWidthOffset;
float x4 = left + width;
float step = height / (majorTicksNum - 1);
int textStep = (int)((Parent.Maximum - Parent.Minimum) / (majorTicksNum - 1));
Font font = e.Cache.GetFont(Font.FontFamily, Parent.IsPrinting ? Font.Size : Font.Size * e.ScaleX * 96f / DrawUtils.ScreenDpi, Font.Style);
string text = Parent.Minimum.ToString();
if (firstSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum; i++)
{
g.DrawLine(pen, x1, y, x2, y);
if (firstSubScale.ShowCaption)
{
SizeF strSize = g.MeasureString(text, Font);
g.DrawString(text, font, brush, x1 - strSize.Width * e.ScaleX / (DrawUtils.ScreenDpi / 96f) - 0.04f * Units.Centimeters * e.ScaleX, y - strSize.Height / 2 * e.ScaleY / (DrawUtils.ScreenDpi / 96f));
text = Convert.ToString(textStep * (i + 1) + Parent.Minimum);
}
y -= step;
}
}
y = top + height;
text = Parent.Minimum.ToString();
if (secondSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum; i++)
{
g.DrawLine(pen, x3, y, x4, y);
if (secondSubScale.ShowCaption)
{
SizeF strSize = g.MeasureString(text, Font);
g.DrawString(text, font, brush, x4 + 0.04f * Units.Centimeters * e.ScaleX, y - strSize.Height / 2 * e.ScaleY / (DrawUtils.ScreenDpi / 96f));
text = Convert.ToString(textStep * (i + 1) + Parent.Minimum);
}
y -= step;
}
}
brush.Dispose();
}
private void DrawMinorTicksVert(FRPaintEventArgs e)
{
IGraphics g = e.Graphics;
Pen pen = e.Cache.GetPen(MinorTicks.Color, MinorTicks.Width * e.ScaleY, DashStyle.Solid);
pointerWidthOffset = (Parent.Pointer as SimplePointer).Width / 2 + Parent.Pointer.BorderWidth * 2 * e.ScaleX;
float y = top + height;
float x1 = left + width * 0.15f;
float x2 = left + width / 2 - pointerWidthOffset;
float x3 = left + width / 2 + pointerWidthOffset;
float x4 = left + width - width * 0.15f;
float step = height / (majorTicksNum - 1) / 4;
if (firstSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum - 1; i++)
{
y -= step;
for (int j = 0; j < 3; j++)
{
g.DrawLine(pen, x1, y, x2, y);
y -= step;
}
}
}
y = top + height;
if (secondSubScale.Enabled)
{
for (int i = 0; i < majorTicksNum - 1; i++)
{
y -= step;
for (int j = 0; j < 3; j++)
{
g.DrawLine(pen, x3, y, x4, y);
y -= step;
}
}
}
}
#endregion // Private Methods
#region Public Methods
///
public override void Assign(GaugeScale src)
{
base.Assign(src);
SimpleScale s = src as SimpleScale;
MajorTicks.Assign(s.MajorTicks);
MinorTicks.Assign(s.MinorTicks);
FirstSubScale.Assign(s.FirstSubScale);
SecondSubScale.Assign(s.SecondSubScale);
}
///
public override void Draw(FastReport.Utils.FRPaintEventArgs e)
{
base.Draw(e);
if (Parent.Vertical)
{
left = (Parent.AbsLeft + 0.7f * Units.Centimeters) * e.ScaleX;
top = (Parent.AbsTop + 0.5f * Units.Centimeters) * e.ScaleY;
height = (Parent.Height - 1.0f * Units.Centimeters) * e.ScaleY;
width = (Parent.Width - 1.4f * Units.Centimeters) * e.ScaleX;
DrawMajorTicksVert(e);
DrawMinorTicksVert(e);
}
else
{
left = (Parent.AbsLeft + 0.5f * Units.Centimeters) * e.ScaleX;
top = (Parent.AbsTop + 0.6f * Units.Centimeters) * e.ScaleY;
height = (Parent.Height - 1.2f * Units.Centimeters) * e.ScaleY;
width = (Parent.Width - 1.0f * Units.Centimeters) * e.ScaleX;
DrawMajorTicksHorz(e);
DrawMinorTicksHorz(e);
}
}
///
public override void Serialize(FRWriter writer, string prefix, GaugeScale diff)
{
base.Serialize(writer, prefix, diff);
SimpleScale dc = diff as SimpleScale;
MajorTicks.Serialize(writer, prefix + ".MajorTicks", dc.MajorTicks);
MinorTicks.Serialize(writer, prefix + ".MinorTicks", dc.MinorTicks);
FirstSubScale.Serialize(writer, prefix + ".FirstSubScale", dc.FirstSubScale);
SecondSubScale.Serialize(writer, prefix + ".SecondSubScale", dc.SecondSubScale);
}
#endregion // Public Methods
}
///
/// Represent the subscale of simple scale.
///
[ToolboxItem(false)]
public class SimpleSubScale : Component
{
#region Fields
private bool enabled;
private bool showCaption;
#endregion // Fields
#region Properties
///
/// Gets or sets a value that specifies enabled subscale or not.
///
[Browsable(true)]
public bool Enabled
{
get { return enabled; }
set { enabled = value; }
}
///
/// Gets or sets a value that specifies show caption or not.
///
[Browsable(true)]
public bool ShowCaption
{
get { return showCaption; }
set { showCaption = value; }
}
#endregion // Properties
#region Constructors
///
/// Initializes a new instance of the class.
///
public SimpleSubScale()
{
enabled = true;
showCaption = true;
}
#endregion // Constructors
#region Public Methods
///
/// Copies the contents of another SimpleSubScale.
///
/// The SimpleSubScale instance to copy the contents from.
public virtual void Assign(SimpleSubScale src)
{
Enabled = src.Enabled;
ShowCaption = src.ShowCaption;
}
///
/// Serializes the SimpleSubScale.
///
/// Writer object.
/// SimpleSubScale property name.
/// Another SimpleSubScale to compare with.
///
/// This method is for internal use only.
///
public virtual void Serialize(FRWriter writer, string prefix, SimpleSubScale diff)
{
if (Enabled != diff.Enabled)
{
writer.WriteBool(prefix + ".Enabled", Enabled);
}
if (ShowCaption != diff.ShowCaption)
{
writer.WriteBool(prefix + ".ShowCaption", ShowCaption);
}
}
#endregion // Public Methods
}
}