100 lines
No EOL
3.8 KiB
C#
100 lines
No EOL
3.8 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using JD.Application.View.Timeline;
|
|
using JD.Audio.Annotations;
|
|
using JD.Kernel.Structs;
|
|
using TeaBox;
|
|
using Signature = JD.Audio.Annotations.Signature;
|
|
|
|
namespace JD.Application.View.Tracks
|
|
{
|
|
/// <summary>
|
|
/// Paints a grid as helper to position elements on the beats / measures.
|
|
/// </summary>
|
|
public class BeatsGrid
|
|
{
|
|
/// <summary>
|
|
/// Paints a dotted line on each beat in the specified bounds.
|
|
/// </summary>
|
|
public static void PaintMeasure(Graphics graphics, Rectangle bounds, global::JD.Sequencers.Times.Timeline timeline, Color color = default(Color))
|
|
{
|
|
const int minimumPixelPerLine = 12;
|
|
|
|
if (color == default(Color))
|
|
{
|
|
color = Color.FromArgb(120, 255, 255, 255);
|
|
}
|
|
|
|
float measureSize = timeline.PixelFromBeatDuration(new BeatUnit(Signature.Default.BeatsPerMeasure));
|
|
if (measureSize < 16)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int drawMeasureOnEach = Math.Max(1, (int)Math.Round(minimumPixelPerLine / measureSize));
|
|
|
|
using (var p = new Pen(color))
|
|
{
|
|
Range<int> paintBounds = new Range<int>(bounds.Left, bounds.Right);
|
|
|
|
var timeRange = timeline.VisibleTimeRange;
|
|
for (int i = (int)timeRange.Min; i < (int)timeRange.Max; i++)
|
|
{
|
|
var beat = new BeatUnit(i);
|
|
var signature = timeline.Wave().Annotations.GetSignature(beat);
|
|
|
|
if (signature.ComputeIndexInMeasure(beat) == 1)
|
|
{
|
|
int pixel = timeline.TimeToPixel(beat);
|
|
|
|
if (paintBounds.Contains(pixel) && (beat.EntireValue / signature.BeatsPerMeasure) % drawMeasureOnEach == 0)
|
|
{
|
|
graphics.DrawLine(p, pixel, bounds.Top, pixel, bounds.Bottom);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void PaintGrid(Graphics graphics, Rectangle bounds, global::JD.Sequencers.Times.Timeline timeline, Color colorBeats, Color colorMeasures)
|
|
{
|
|
const float quarterBeatDuration = 0.25f;
|
|
const float beatDuration = 1f;
|
|
const int minimumPixelPerLine = 10;
|
|
|
|
PaintMeasure(graphics, bounds, timeline, colorMeasures);
|
|
|
|
float quarterBeatPixelSize = timeline.PixelFromBeatDuration(new BeatUnit(quarterBeatDuration));
|
|
float beatPixelSize = timeline.PixelFromBeatDuration(new BeatUnit(beatDuration));
|
|
if (beatPixelSize < minimumPixelPerLine)
|
|
{
|
|
return;
|
|
}
|
|
|
|
using (var p = new Pen(colorBeats))
|
|
{
|
|
var paintBounds = new Range<int>(bounds.Left, bounds.Right);
|
|
|
|
var timeRange = timeline.VisibleTimeRange;
|
|
var minTime = timeRange.Min - timeRange.Min%quarterBeatDuration;
|
|
|
|
for (float beat = minTime; beat < timeRange.Max; beat += quarterBeatDuration)
|
|
{
|
|
int pixel = timeline.TimeToPixel(beat);
|
|
bool isBeat = Math.Abs(beat % beatDuration) < float.Epsilon;
|
|
if (paintBounds.Contains(pixel))
|
|
{
|
|
if (isBeat)
|
|
{
|
|
graphics.DrawLine(p, pixel, bounds.Bottom-2, pixel, bounds.Bottom - 7);
|
|
}
|
|
else if (quarterBeatPixelSize > minimumPixelPerLine)
|
|
{
|
|
graphics.DrawLine(p, pixel, bounds.Bottom-2, pixel, bounds.Bottom - 4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |