// Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Drag;
using FlaxEditor.GUI.Input;
using FlaxEditor.GUI.Timeline.GUI;
using FlaxEditor.GUI.Timeline.Tracks;
using FlaxEditor.GUI.Timeline.Undo;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI.Timeline
{
///
/// The timeline control that contains tracks section and headers. Can be used to create time-based media interface for camera tracks editing, audio mixing and events tracking.
///
[HideInEditor]
public partial class Timeline : ContainerControl, IKeyframesEditorContext
{
private static readonly KeyValuePair[] FPSValues =
{
new KeyValuePair(12f, "12 fps"),
new KeyValuePair(15f, "15 fps"),
new KeyValuePair(23.976f, "23.97 (NTSC)"),
new KeyValuePair(24f, "24 fps"),
new KeyValuePair(25f, "25 (PAL)"),
new KeyValuePair(30f, "30 fps"),
new KeyValuePair(48f, "48 fps"),
new KeyValuePair(50f, "50 (PAL)"),
new KeyValuePair(60f, "60 fps"),
new KeyValuePair(100f, "100 fps"),
new KeyValuePair(120f, "120 fps"),
new KeyValuePair(240f, "240 fps"),
new KeyValuePair(0, "Custom"),
};
internal const int FormatVersion = 4;
///
/// The base class for timeline properties proxy objects.
///
/// The type of the timeline.
public abstract class ProxyBase
where TTimeline : Timeline
{
///
/// The timeline reference.
///
[HideInEditor, NoSerialize]
public TTimeline Timeline;
///
/// Gets or sets the total duration of the timeline (in frames).
///
[EditorDisplay("General"), EditorOrder(10), Limit(1), VisibleIf(nameof(UseFrames)), Tooltip("Total duration of the timeline (in frames).")]
public int DurationFrames
{
get => Timeline.DurationFrames;
set => Timeline.DurationFrames = value;
}
///
/// Gets or sets the total duration of the timeline (in seconds).
///
[EditorDisplay("General"), EditorOrder(10), Limit(0.0f, float.MaxValue, 0.001f), VisibleIf(nameof(UseFrames), true), Tooltip("Total duration of the timeline (in seconds).")]
public float Duration
{
get => Timeline.Duration;
set => Timeline.Duration = value;
}
private bool UseFrames => Timeline.TimeShowMode == TimeShowModes.Frames;
///
/// Initializes a new instance of the class.
///
/// The timeline.
protected ProxyBase(TTimeline timeline)
{
Timeline = timeline ?? throw new ArgumentNullException(nameof(timeline));
}
}
///
/// The time axis value formatting modes.
///
public enum TimeShowModes
{
///
/// The frame numbers.
///
Frames,
///
/// The seconds amount.
///
Seconds,
///
/// The time.
///
Time,
}
///
/// The timeline animation playback states.
///
public enum PlaybackStates
{
///
/// The timeline animation feature is disabled.
///
Disabled,
///
/// The timeline animation feature is disabled except for current frame seeking.
///
Seeking,
///
/// The timeline animation is stopped.
///
Stopped,
///
/// The timeline animation is playing.
///
Playing,
///
/// The timeline animation is paused.
///
Paused,
}
///
/// The timeline playback buttons types.
///
[Flags]
public enum PlaybackButtons
{
///
/// No buttons.
///
None = 0,
///
/// The play/pause button.
///
Play = 1,
///
/// The stop button.
///
Stop = 2,
///
/// The current frame navigation buttons (left/right frame, seep begin/end).
///
Navigation = 4,
}
///
/// The header top area height (in pixels).
///
public static readonly float HeaderTopAreaHeight = 40.0f;
///
/// The timeline units per second (on time axis).
///
public static readonly float UnitsPerSecond = 100.0f;
///
/// The start offset for the timeline (on time axis).
///
public static readonly float StartOffset = 50.0f;
private bool _isChangingFps;
private float _framesPerSecond = 30.0f;
private int _durationFrames = 30 * 5;
private int _currentFrame;
private TimeShowModes _timeShowMode = TimeShowModes.Frames;
private bool _showPreviewValues = true;
private PlaybackStates _state = PlaybackStates.Disabled;
///
/// The Track that is being dragged over. This could have a value when not dragging.
///
internal Track DraggedOverTrack = null;
///
/// Flag used to mark modified timeline data.
///
protected bool _isModified;
///
/// The tracks collection.
///
protected readonly List