JD2022-TU1/main/tools/apps/AutoDance/Project/Source/View/AutoDancePrewiewVideoPad.cs

135 lines
4.7 KiB
C#

using System;
using System.Linq;
using System.Windows.Forms;
using JD.Application.Utils;
using JD.Application.View.Timeline;
using JD.Audio.Annotations;
using JD.Maths.Utils;
using JD.Timeline.Document;
using JD.Timeline.View.ClipView;
using JD.VideoPlayer.Project;
using TeaBox;
using TeaBox.ObjectModel;
using JD.Serialization;
using Application = TeaBox.ObjectModel.Application;
namespace AutoDance.View
{
public class AutoDancePrewiewVideoPad : AbstractPadContent
{
private readonly Control _control;
private TapeDocumentView _currentReplayView;
#region Properties
#endregion
public AutoDancePrewiewVideoPad()
{
_control = new PictureBox { Dock = DockStyle.Fill };
_control.Paint += _control_Paint;
_control.HandleCreated += _control_HandleCreated;
Application.Main.Views.SelectedItemChanged += Views_SelectedItemChanged;
}
public override Control Control
{
get { return _control; }
}
private TapeDocumentView CurrentReplayReplayView
{
get { return _currentReplayView; }
set
{
if (_currentReplayView != null)
{
_currentReplayView.ClipView.Timeline.CurrentTimeChanged -= CurrentView_Changed;
_currentReplayView.Document.Tape.PropertyChanged -= CurrentView_Changed;
}
_currentReplayView = value;
if (_currentReplayView != null)
{
// When updating the content of a clip, update the time so we get the preview right now.
_currentReplayView.ClipView.Timeline.CurrentTimeChanged += CurrentView_Changed;
_currentReplayView.Document.Tape.PropertyChanged += CurrentView_Changed;
}
}
}
private void CurrentView_Changed(object sender, EventArgs e)
{
_control.Invalidate();
}
void _control_Paint(object sender, PaintEventArgs e)
{
var currentView = CurrentReplayReplayView;
if (currentView != null)
{
var currentTime = currentView.ClipView.Timeline.BeatFromTimeUnit(currentView.ClipView.Timeline.TimeCursor.Time);
var toPaint = ComputePlayingBeat(currentTime);
currentView.ClipView.Tape.VideoSpriteSheet().Paint(e.Graphics, toPaint, e.ClipRectangle);
}
}
private void _control_HandleCreated(object sender, EventArgs e)
{
Views_SelectedItemChanged(null, null);
}
private void Views_SelectedItemChanged(object sender, EventArgs e)
{
CurrentReplayReplayView = Application.Main.Views.SelectedItem as TapeDocumentView;
}
public BeatUnit ComputePlayingBeat(BeatUnit currentBeat)
{
if (_currentReplayView == null || _currentReplayView.Document.Tape.TryGetWave() == null)
{
return new BeatUnit(0);
}
BeatUnit replayBeat;
var autoDanceDocumentView = Application.Main.Views.SelectedItem as AutoDanceDocumentView;
if (autoDanceDocumentView != null && ComputeReplayTime(autoDanceDocumentView, currentBeat.Value, out replayBeat))
{
currentBeat = replayBeat;
}
return currentBeat;
}
private bool ComputeReplayTime(AutoDanceDocumentView view, float currentTime, out BeatUnit replayTime)
{
// We use the first replay clip that is under the current time cursor
// but if there is also a record clip at the same time that is selected, we use this one first...
var document = (AutoDanceDocument)view.MainDocument;
var activeTrackWidget = view.ClipView.TrackView.ActiveTrack as TapeTrackWidget;
var activeClipType = activeTrackWidget == null ? null : activeTrackWidget.Track.ClipTypes().FirstOrDefault();
var prospects = (from clip in document.Tape.Clips
where currentTime.IsBetween(clip.StartBeat, clip.StopBeat - 0.001f)
where clip is ReplayClipNew || clip is RecordClipMarker
orderby clip.GetType() == activeClipType descending
select clip);
var replayClip = prospects.FirstOrDefault() as ReplayClipNew;
if (replayClip != null)
{
return replayClip.GetReplayBeat(currentTime, out replayTime);
}
replayTime = new BeatUnit(0);
return false;
}
}
}