121 lines
3.6 KiB
C#
121 lines
3.6 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using JD.Application.View.Timeline;
|
|
using JD.Application.View.Utilities;
|
|
using JD.Audio.Annotations;
|
|
using JD.Audio.Sound;
|
|
using JD.Kernel.StaticHelpers;
|
|
using TeaBox;
|
|
using Point = System.Drawing.Point;
|
|
using Size = System.Drawing.Size;
|
|
|
|
namespace JD.Application.View.Tracks
|
|
{
|
|
/// <summary>
|
|
/// Paints the wave as a track in the Sequence
|
|
/// </summary>
|
|
public class WaveTrack : AnnotationTrack
|
|
{
|
|
private readonly PaintCache _cache = new PaintCache();
|
|
private readonly Wave _wave;
|
|
private readonly IChannel _channel;
|
|
|
|
public WaveTrack(Wave wave, IChannel channel)
|
|
: base(wave.Annotations)
|
|
{
|
|
Throw.IfNull(wave, "wave");
|
|
Throw.IfNull(channel, "channel");
|
|
|
|
_wave = wave;
|
|
_wave.AsyncLoaded += _wave_AsyncLoaded;
|
|
_channel = channel;
|
|
_cache.Refreshed += (s, e) => Invalidate();
|
|
}
|
|
|
|
void _wave_AsyncLoaded(object sender, EventArgs e)
|
|
{
|
|
_cache.Invalidate();
|
|
Invalidate();
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
_wave.AsyncLoaded -=_wave_AsyncLoaded;
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
protected override void OnPaintSelf(PaintEventArgs e)
|
|
{
|
|
base.OnPaintSelf(e);
|
|
|
|
int start = Timeline.TimeToPixel(Timeline.VisibleTimeRange.Min);
|
|
int end = Timeline.TimeToPixel(Timeline.VisibleTimeRange.Max);
|
|
|
|
var image = _cache.GetImage(new PaintRequest
|
|
{
|
|
Channel = _channel,
|
|
Wave = _wave,
|
|
Start = Timeline.VisibleStartBeat(),
|
|
End = Timeline.VisibleEndBeat(),
|
|
Size = new Size(end - start, Bounds.Height - 1),
|
|
});
|
|
|
|
if (image != null)
|
|
{
|
|
e.Graphics.DrawImage(image, new Point(Bounds.Left + start, Bounds.Top));
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return Path.GetFileName(_wave.FileName) ?? "No wave found";
|
|
}
|
|
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
{
|
|
base.OnMouseDown(e);
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
Timeline.TimeCursor.Time = Timeline.PixelToTime(e.X);
|
|
}
|
|
}
|
|
|
|
#region Nested
|
|
|
|
private struct PaintRequest
|
|
{
|
|
public IChannel Channel;
|
|
public Wave Wave;
|
|
public BeatUnit Start;
|
|
public BeatUnit End;
|
|
public Size Size;
|
|
}
|
|
|
|
private class PaintCache : AsyncPaintCache<PaintRequest>
|
|
{
|
|
protected override Image DoPaint(PaintRequest request)
|
|
{
|
|
if (request.Size.Width == 0 || request.Size.Height == 0)
|
|
{
|
|
return new Bitmap(1, 1);
|
|
}
|
|
|
|
var curve = new GraphicalWaveCurve();
|
|
float beatsLength = request.End.Value - request.Start.Value;
|
|
float pixelsPerBeat = request.Size.Width / beatsLength;
|
|
curve.AddBeats(request.Channel, request.Wave.UnitConverter, request.Start, request.End, pixelsPerBeat);
|
|
|
|
var bitmap = new Bitmap(request.Size.Width, request.Size.Height);
|
|
using (var graphics = Graphics.FromImage(bitmap))
|
|
{
|
|
curve.Paint(graphics, request.Start, request.Size.Height, pixelsPerBeat, LowQuality);
|
|
}
|
|
return bitmap;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|