protected void DrawRuler(Graphics g, TimelineViewControlRenderer r, Rectangle rect, bool left) { float visibleValueSpan = Math.Abs(this.verticalUnitTop - this.verticalUnitBottom); int valueDecimals = Math.Max(0, -(int)Math.Log10(visibleValueSpan) + 2); string verticalTopText = string.Format( System.Globalization.CultureInfo.InvariantCulture, "{0:F" + valueDecimals + "}", this.verticalUnitTop); string verticalBottomText = string.Format( System.Globalization.CultureInfo.InvariantCulture, "{0:F" + valueDecimals + "}", this.verticalUnitBottom); SizeF verticalTopTextSize = g.MeasureString(verticalTopText, r.FontSmall); SizeF verticalBottomTextSize = g.MeasureString(verticalBottomText, r.FontSmall); // Draw background Rectangle borderRect; if (this.ParentView.BorderStyle != System.Windows.Forms.BorderStyle.None) { borderRect = new Rectangle( rect.X - (left ? 1 : 0), rect.Y, rect.Width + 1, rect.Height); } else { borderRect = rect; } g.FillRectangle(new SolidBrush(r.ColorVeryLightBackground), rect); r.DrawBorder(g, borderRect, Drawing.BorderStyle.Simple, BorderState.Normal); // Determine drawing geometry Rectangle rectTrackName; Rectangle rectUnitMarkings; Rectangle rectUnitRuler; { float markingRatio = 0.5f + 0.5f * (1.0f - Math.Max(Math.Min((float)rect.Height / 32.0f, 1.0f), 0.0f)); rectTrackName = new Rectangle( rect.X, rect.Y, Math.Min(rect.Width, r.FontRegular.Height + 2), rect.Height); rectUnitMarkings = new Rectangle( rect.Right - Math.Min((int)(rect.Width * markingRatio), 16), rect.Y, Math.Min((int)(rect.Width * markingRatio), 16), rect.Height); int maxUnitWidth = Math.Max(Math.Max(rectUnitMarkings.Width, (int)verticalTopTextSize.Width + 2), (int)verticalBottomTextSize.Width + 2); rectUnitRuler = new Rectangle( rect.Right - maxUnitWidth, rect.Y, maxUnitWidth, rect.Height); if (!left) { rectTrackName.X = rect.Right - (rectTrackName .X - rect.Left) - rectTrackName .Width; rectUnitMarkings.X = rect.Right - (rectUnitMarkings.X - rect.Left) - rectUnitMarkings .Width; rectUnitRuler.X = rect.Right - (rectUnitRuler .X - rect.Left) - rectUnitRuler .Width; } } // Draw track name { Rectangle overlap = rectUnitMarkings; overlap.Intersect(rectTrackName); float overlapAmount = Math.Max(Math.Min((float)overlap.Width / (float)rectTrackName.Width, 1.0f), 0.0f); float textOverlapAlpha = (1.0f - (overlapAmount)); StringFormat format = new StringFormat(StringFormat.GenericDefault); format.Trimming = StringTrimming.EllipsisCharacter; SizeF textSize = g.MeasureString(this.Model.TrackName, r.FontRegular, rectTrackName.Height, format); var state = g.Save(); g.TranslateTransform( rectTrackName.X + (int)textSize.Height + 2, rectTrackName.Y); g.RotateTransform(90); g.DrawString( this.Model.TrackName, r.FontRegular, new SolidBrush(Color.FromArgb((int)(textOverlapAlpha * 255), r.ColorText)), new Rectangle(0, 0, rectTrackName.Height, rectTrackName.Width), format); g.Restore(state); } // Draw vertical unit markings { Pen bigLinePen = new Pen(new SolidBrush(r.ColorRulerMarkMajor)); Pen medLinePen = new Pen(new SolidBrush(r.ColorRulerMarkRegular)); Pen minLinePen = new Pen(new SolidBrush(r.ColorRulerMarkMinor)); // Static Top and Bottom marks SizeF textSize; textSize = g.MeasureString(verticalTopText, r.FontSmall); g.DrawString(verticalTopText, r.FontSmall, new SolidBrush(r.ColorText), left ? rectUnitMarkings.Right - textSize.Width : rectUnitMarkings.Left, rectUnitMarkings.Top); textSize = g.MeasureString(verticalBottomText, r.FontSmall); g.DrawString(verticalBottomText, r.FontSmall, new SolidBrush(r.ColorText), left ? rectUnitMarkings.Right - textSize.Width : rectUnitMarkings.Left, rectUnitMarkings.Bottom - textSize.Height - 1); // Dynamic Inbetween marks foreach (TimelineViewRulerMark mark in this.GetVisibleRulerMarks()) { float markLen; Pen markPen; bool bigMark; switch (mark.Weight) { case TimelineViewRulerMarkWeight.Major: markLen = 0.5f; markPen = bigLinePen; bigMark = true; break; default: case TimelineViewRulerMarkWeight.Regular: case TimelineViewRulerMarkWeight.Minor: markLen = 0.25f; markPen = medLinePen; bigMark = false; break; } int borderDistInner = r.FontSmall.Height / 2; int borderDistOuter = r.FontSmall.Height / 2 + 15; float borderDist = (float)Math.Min(Math.Abs(mark.PixelValue - rect.Top), Math.Abs(mark.PixelValue - rect.Bottom)); float markTopX; float markBottomX; if (left) { markTopX = rectUnitMarkings.Right - markLen * rectUnitMarkings.Width; markBottomX = rectUnitMarkings.Right; } else { markTopX = rectUnitMarkings.Left; markBottomX = rectUnitMarkings.Left + markLen * rectUnitMarkings.Width; } if (borderDist > borderDistInner) { float alpha = Math.Min(1.0f, (float)(borderDist - borderDistInner) / (float)(borderDistOuter - borderDistInner)); Color markColor = Color.FromArgb((int)(alpha * markPen.Color.A), markPen.Color); Color textColor = Color.FromArgb((int)(alpha * markPen.Color.A), r.ColorText); g.DrawLine(new Pen(markColor), (int)markTopX, (int)mark.PixelValue, (int)markBottomX, (int)mark.PixelValue); if (bigMark) { string text = string.Format( System.Globalization.CultureInfo.InvariantCulture, "{0:F" + valueDecimals + "}", mark.UnitValue); textSize = g.MeasureString(text, r.FontSmall); g.DrawString( text, r.FontSmall, new SolidBrush(textColor), left ? markTopX - textSize.Width : markBottomX, mark.PixelValue - textSize.Height * 0.5f); } } } } }
protected void DrawLegend(Graphics g, TimelineViewControlRenderer r, Rectangle rect) { // Draw background Rectangle borderRect; if (this.ParentView.BorderStyle != System.Windows.Forms.BorderStyle.None) { borderRect = new Rectangle( rect.X, rect.Y, rect.Width + 1, rect.Height); } else { borderRect = rect; } g.FillRectangle(new SolidBrush(r.ColorVeryLightBackground), rect); r.DrawBorder(g, borderRect, Drawing.BorderStyle.Simple, BorderState.Normal); }