JD2022-TU1/main/tools/framework/JD.Timeline/Dance/MoveReferenceVideoPad.cs

133 lines
No EOL
5 KiB
C#

using System.Drawing;
using System.Linq;
using JD.Timeline.Document;
using JD.Timeline.Model;
using JD.Timeline.View.ClipView.Widgets;
using TeaBox.ObjectModel;
using JD.Serialization;
using JD.Application.Utils;
using JD.Application.View.Actions;
using JD.Audio.Annotations;
using JD.Interfaces.Player;
using JD.VideoPlayer.Project;
namespace JD.Timeline.View.Pads
{
/// <summary>
/// Shows the corresponding instance of the moves.
/// </summary>
public class MoveReferenceVideoPad : WaveControlledVideoPad
{
private readonly MoveReferenceConductor _conductor;
public MoveReferenceVideoPad()
{
_conductor = new MoveReferenceConductor();
Initialize();
}
protected override PleoConductor Conductor
{
get { return _conductor; }
}
protected override IPlayerProvider GetPlayerProvider(IView view)
{
// Here we cheat a bit, we try to find the wave control if possible because
// as some other spots, we are considering the player provider is a wave control in order to make it work
// with selected clip changed.
var tapeDocumentView = view as TapeDocumentView;
Control.Visible = tapeDocumentView == null || tapeDocumentView.Document.IsLoadedFromFile;
return (null != tapeDocumentView) ? tapeDocumentView.ClipView : base.GetPlayerProvider(view);
}
protected override VideoControl CreateVideoControl()
{
var control = base.CreateVideoControl();
control.Paint += control_Paint;
return control;
}
void control_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
if (_conductor.ReferenceMove == null)
{
using (var brush = new SolidBrush(VideoControl.BackColor))
{
e.Graphics.FillRectangle(brush, 0, 0, VideoControl.Width, VideoControl.Height);
VideoControl.PaintText(e);
}
}
}
protected override void UpdateConductors()
{
float currentTime = PlayerProvider.Player.CurrentTime;
_conductor.UpdateLocalTime(currentTime);
var referenceMove = _conductor.ReferenceMove;
if (referenceMove != null)
{
var coachId = MotionClip.CoachId_Enum.COACH_NONE;
if (referenceMove.Track is MoveTrack)
coachId = ((MoveTrack) referenceMove.Track).CoachId;
VideoControl.Text = $"{referenceMove.Model.Name} ({coachId}, beat {referenceMove.StartBeat})";
}
else if (_conductor.CurrentMove != null)
{
VideoControl.Text = $"No other instance of move '{_conductor.CurrentMove.Model.Name}'";
}
else
{
VideoControl.Text = string.Empty;
}
}
private class MoveReferenceConductor : PleoConductor
{
public MotionClip CurrentMove { get; set; }
public MotionClip ReferenceMove { get; set; }
public override void ReloadClip()
{
var view = TeaBox.ObjectModel.Application.Main.Views.SelectedItem as TapeDocumentView;
if (view != null)
{
Wave = view.Document.Tape.TryGetWave();
Clip = LoadVideoClip(FindPreviewVideoFile(view.Document.Tape.Map()));
}
}
public void UpdateLocalTime(float currentTime)
{
var view = TeaBox.ObjectModel.Application.Main.Views.SelectedItem as TapeDocumentView;
if (view != null)
{
CurrentMove = (from widget in view.ClipView.ClipWidgets.OfType<MotionClipWidget>()
where widget.Model.StartBeat <= currentTime &&
widget.Model.StopBeat >= currentTime &&
widget.Track == view.ClipView.TrackView.ActiveTrack
select widget.Model).FirstOrDefault();
double videoTime = -1;
ReferenceMove = null;
if (CurrentMove != null)
{
ReferenceMove = CurrentMove.Model.Instances.FirstOrDefault(instance => instance.StartFrame != CurrentMove.StartFrame);
if (ReferenceMove != null)
{
var beatRelativeToMove = currentTime - CurrentMove.StartBeat;
var beatToPlay = new BeatUnit(ReferenceMove.StartBeat + beatRelativeToMove);
videoTime = (Wave.UnitConverter.TimeFromBeat(beatToPlay) - Wave.Annotations.VideoStartTime).TotalSeconds;
}
}
LocalTime = videoTime;
}
}
}
}
}