150 lines
No EOL
4.6 KiB
C#
150 lines
No EOL
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using JD.Application.View.TrackItems;
|
|
using JD.Audio.Annotations;
|
|
using JD.Sequencers.Controls;
|
|
|
|
namespace JD.Application.View.Tracks
|
|
{
|
|
/// <summary>
|
|
/// Base class for wave tracks that paints the song parts behing the track.
|
|
/// </summary>
|
|
public class WaveTrackBase : Track
|
|
{
|
|
private AnnotationCollection _annotations;
|
|
private int _minimumHeight = 24;
|
|
private int _maximumHeight = int.MaxValue;
|
|
|
|
/// <summary>
|
|
/// True when the items does overlap the maximum height of the track
|
|
/// </summary>
|
|
private int _annotationOverflows;
|
|
|
|
public WaveTrackBase()
|
|
{
|
|
}
|
|
|
|
public WaveTrackBase(AnnotationCollection annotations)
|
|
{
|
|
_annotations = annotations;
|
|
}
|
|
|
|
public virtual AnnotationCollection Annotations
|
|
{
|
|
get { return _annotations; }
|
|
set { _annotations = value; }
|
|
}
|
|
|
|
public int MinimumHeight
|
|
{
|
|
get { return _minimumHeight; }
|
|
set
|
|
{
|
|
_minimumHeight = value;
|
|
Height = value;
|
|
}
|
|
}
|
|
|
|
public int MaximumHeight
|
|
{
|
|
get { return _maximumHeight; }
|
|
set { _maximumHeight = value; }
|
|
}
|
|
|
|
public override void ComputeChildBounds(Graphics graphics)
|
|
{
|
|
List<Rectangle> rectangles = new List<Rectangle>();
|
|
_annotationOverflows = 0;
|
|
|
|
int height = MinimumHeight;
|
|
var items = Children.OfType<AnnotationTrackItem>().OrderBy(item => item.Time.Value * 1);
|
|
|
|
if (_maximumHeight < items.FirstOrDefault()?.Height*2)
|
|
{
|
|
ArrangeItemsOnSingleRow(graphics, items);
|
|
return;
|
|
}
|
|
|
|
foreach (var trackItem in items)
|
|
{
|
|
trackItem.UpdatePosition(graphics, rectangles);
|
|
rectangles.Add(trackItem.RelativeBounds);
|
|
|
|
// Clean the used space, we do not need to consider it anymore
|
|
var currentX = trackItem.RelativeBounds.X;
|
|
rectangles.RemoveAll(rect => rect.Right < currentX);
|
|
|
|
int newHeight = -trackItem.RelativeBounds.Y;
|
|
|
|
trackItem.ShowLabel = newHeight <= _maximumHeight - trackItem.Height;
|
|
|
|
if (!trackItem.ShowLabel)
|
|
{
|
|
_annotationOverflows = Math.Max(_annotationOverflows, trackItem.Height + 1);
|
|
var bounds = trackItem.RelativeBounds;
|
|
bounds.Y = -Height;
|
|
trackItem.RelativeBounds = bounds;
|
|
}
|
|
|
|
height = Math.Max(height, newHeight);
|
|
}
|
|
|
|
Height = Math.Min(height, MaximumHeight);
|
|
}
|
|
|
|
private void ArrangeItemsOnSingleRow(Graphics graphics, IEnumerable<AnnotationTrackItem> items)
|
|
{
|
|
AnnotationTrackItem previousItem = null;
|
|
var noSpace = new List<Rectangle>();
|
|
|
|
foreach (var item in items)
|
|
{
|
|
item.UpdatePosition(graphics, noSpace);
|
|
item.ShowLabel = true;
|
|
|
|
if (previousItem != null && previousItem.Bounds.IntersectsWith(item.Bounds))
|
|
{
|
|
previousItem.ShowLabel = false;
|
|
}
|
|
previousItem = item;
|
|
}
|
|
}
|
|
|
|
public override void FinalizeChildBounds(Graphics graphics)
|
|
{
|
|
foreach (var trackItem in Children.OfType<AnnotationTrackItem>())
|
|
{
|
|
var bounds = trackItem.RelativeBounds;
|
|
bounds.Y += Bounds.Bottom;
|
|
trackItem.Bounds = bounds;
|
|
}
|
|
}
|
|
|
|
protected override void AlignTrackItemBounds(TrackItem item)
|
|
{
|
|
// Items are repositionned automatically on paint.
|
|
}
|
|
|
|
protected override void OnPaintBackground(PaintEventArgs e)
|
|
{
|
|
if (_annotationOverflows > 0)
|
|
{
|
|
var rect = Bounds;
|
|
rect.Y -= 1; // To make sure the gradient is inside the bounds of the track.
|
|
rect.Height = _annotationOverflows;
|
|
|
|
using (var brush = new LinearGradientBrush(rect, Color.FromArgb(200, 0, 0, 0), Color.FromArgb(30, 0, 0, 0), LinearGradientMode.Vertical))
|
|
{
|
|
e.Graphics.FillRectangle(brush, rect);
|
|
}
|
|
}
|
|
|
|
// No background color.
|
|
// base.OnPaintBackground(e);
|
|
}
|
|
}
|
|
} |