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 } }