163 lines
6.6 KiB
C#
163 lines
6.6 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using JD.Application.Utils;
|
|
using JD.Core.Collections;
|
|
using JD.Kernel.Structs;
|
|
using JD.Timeline.Document;
|
|
using JD.Timeline.Model.Clips;
|
|
using JD.Timeline.View.ClipView;
|
|
using TeaBox;
|
|
using TeaBox.ObjectModel;
|
|
using JD.Serialization;
|
|
using LinearGradientBrush = System.Drawing.Drawing2D.LinearGradientBrush;
|
|
|
|
namespace JD.Timeline.Dance
|
|
{
|
|
public class PictogramScrollingPad : AbstractPadContent
|
|
{
|
|
private readonly PictogramScrollingControl _control = new PictogramScrollingControl();
|
|
|
|
public PictogramScrollingPad()
|
|
{
|
|
TeaBox.ObjectModel.Application.Main.Views.SelectedItemChanged += Views_SelectedItemChanged;
|
|
Views_SelectedItemChanged(null, null);
|
|
}
|
|
|
|
public override Control Control
|
|
{
|
|
get { return _control; }
|
|
}
|
|
|
|
#region Methods
|
|
|
|
private void Views_SelectedItemChanged(object sender, EventArgs e)
|
|
{
|
|
var view = TeaBox.ObjectModel.Application.Main.Views.SelectedItem as TapeDocumentView;
|
|
if (view != null)
|
|
{
|
|
_control.ClipViewControl = view.ClipView;
|
|
}
|
|
else
|
|
{
|
|
_control.ClipViewControl = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
class PictogramScrollingControl : Control
|
|
{
|
|
private ClipViewControl _clipViewControl;
|
|
|
|
public PictogramScrollingControl()
|
|
{
|
|
//BackColor = System.Drawing.Color.DarkGray;
|
|
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw |
|
|
ControlStyles.ContainerControl | ControlStyles.OptimizedDoubleBuffer, true);
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs pe)
|
|
{
|
|
|
|
pe.Graphics.FillRectangle(new LinearGradientBrush(Bounds, System.Drawing.Color.WhiteSmoke, System.Drawing.Color.FromArgb(200, 235, 245), LinearGradientMode.Vertical), Bounds);
|
|
|
|
if (ClipViewControl == null)
|
|
return;
|
|
|
|
var scrollDurationInBeats = (float)PictogramScrollingUtils.GetScrollDurationInBeats(ClipViewControl.Player.CurrentTime, ClipViewControl.Tape.TryGetWave().UnitConverter);
|
|
var beatRange = new Range<float>(ClipViewControl.Player.CurrentTime, ClipViewControl.Player.CurrentTime + scrollDurationInBeats);
|
|
|
|
//We compute the range in beats of every pictograms
|
|
var pictoRanges = from clip in ClipViewControl.Tape.Clips.OfType<PictogramClip>()
|
|
let stopBeat = clip.StartBeat + PictogramScrollingUtils.GetBeatsPerPixel(_clipViewControl.Tape.DancePlayersCount, clip.StartBeat, _clipViewControl.Tape.TryGetWave().UnitConverter) * clip.Model.BitmapHandler().PictoExpectedSize.Width
|
|
select new
|
|
{
|
|
Clip = clip,
|
|
Range = new Range<float>(clip.StartBeat, (float)stopBeat)
|
|
};
|
|
|
|
//We check wich pictograms have to be painted
|
|
var pictosToDisplay = pictoRanges.Where(x => beatRange.Intersects(x.Range));
|
|
foreach (var picto in pictosToDisplay)
|
|
{
|
|
//When the control is small we use the pictogram thumbnail instead of the full resolution one
|
|
var bitmap = Size.Height > 200 ? picto.Clip.Model.BitmapHandler().Bitmap : picto.Clip.Model.BitmapHandler().BitmapThumbnail;
|
|
if (bitmap == null)
|
|
continue;
|
|
|
|
lock (bitmap)
|
|
{
|
|
try
|
|
{
|
|
//We compute all the pixels coordinates of the pictogram in current control
|
|
var x = Size.Width * (picto.Clip.StartBeat - beatRange.Min) / beatRange.Width();
|
|
var width = Size.Width * picto.Range.Width() / beatRange.Width();
|
|
var heigth = width * bitmap.Height / bitmap.Width;
|
|
var y = (Size.Height - heigth) / 2F;
|
|
|
|
//We compute the progress of the disappearing of the pictogram, and apply opacity modification and vertical translation
|
|
//in case it's disappearing
|
|
float disappearProgress = x < 0 ? -x / width : 0;
|
|
float opacity = Math.Min(1, 1 - 1.8F * disappearProgress);
|
|
if (disappearProgress > 0)
|
|
{
|
|
x = 0;
|
|
y -= 0.4F * heigth * disappearProgress;
|
|
}
|
|
|
|
//We apply an opacity on the bitmap
|
|
var colormatrix = new ColorMatrix { Matrix33 = opacity };
|
|
var imgAttribute = new ImageAttributes();
|
|
imgAttribute.SetColorMatrix(colormatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
|
|
|
|
pe.Graphics.DrawImage(bitmap, new Rectangle((int)x, (int)y, (int)width, (int)heigth), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, imgAttribute);
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
// Image is not thread safe,
|
|
// when used in another thread that does not lock, just do not paint!
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public ClipViewControl ClipViewControl
|
|
{
|
|
get { return _clipViewControl; }
|
|
set
|
|
{
|
|
if (_clipViewControl != null)
|
|
{
|
|
_clipViewControl.Player.TimeChanged -= Player_TimeChanged;
|
|
_clipViewControl.Tape.Clips.ItemChanged -= Clips_ItemChanged;
|
|
}
|
|
_clipViewControl = value;
|
|
if (_clipViewControl != null)
|
|
{
|
|
_clipViewControl.Player.TimeChanged += Player_TimeChanged;
|
|
_clipViewControl.Tape.Clips.ItemChanged += Clips_ItemChanged;
|
|
}
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void Clips_ItemChanged(object sender, ItemChangedEventArgs<Clip> args)
|
|
{
|
|
//When the start time of a clip change, we want to refresh the painting
|
|
if (args.PropertyName == "StartTime")
|
|
{
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void Player_TimeChanged(object sender, EventArgs e)
|
|
{
|
|
Invalidate();
|
|
}
|
|
}
|
|
}
|