#nullable enable using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; namespace T3.Editor.Gui.Windows.TimeLine; /// /// Persisted per-symbol timeline state. Stored under "Timeline" in the .t3ui Settings block. /// internal sealed class TimelineState { // View public float ScaleX = 1; public float ScrollX; // Mode [JsonConverter(typeof(StringEnumConverter))] public TimeLineCanvas.Modes Mode = TimeLineCanvas.Modes.DopeView; // Layout public int TimelineHeight = -1; // -1 = auto-computed // Inline DataClip edit area — toggled via the AudioFile icon next to the Record button // on the timeline toolbar. When on AND a TimeClip with a DataClip output is selected, // the TimelineDetailsArea pane below the dope sheet resolves to clip-editing mode. public bool InlineDataClipEditEnabled = false; /// /// User-controlled height of the inline details pane (curve editor OR DataClip editor /// — both share one pane and one persisted height). Resized via the splitter above /// the pane. Default 200 px roughly matches the previous curve area's auto-fit at a /// typical timeline height; the splitter clamps to a sensible band so the pane can't /// collapse to nothing or eat the whole timeline. /// public float DetailsAreaHeight = 200f; /// /// Back-compat alias for . Older .t3ui files persisted /// the per-mode "InlineDataClipStripHeight"; Newtonsoft's deserializer surfaces it /// here and we forward the value in . Kept private so /// nothing else writes through it. /// [JsonProperty(Required = Required.Default)] private float? InlineDataClipStripHeight { get; set; } #region Serialization internal void WriteToJson(JsonTextWriter writer) { writer.WritePropertyName("Timeline"); writer.WriteRawValue(JsonConvert.SerializeObject(this, Formatting.Indented)); } internal static TimelineState? ReadFromJson(JToken? settingsToken) { if (settingsToken == null) return null; var token = settingsToken["Timeline"]; var state = token?.ToObject(); if (state == null) return null; // Back-compat: forward the legacy per-mode field onto the unified one when the // .t3ui predates the merge. Wins over the default 200 px but loses to any // explicit DetailsAreaHeight that's also present in the file. if (state.InlineDataClipStripHeight is { } legacy && state.DetailsAreaHeight == 200f) state.DetailsAreaHeight = legacy; return state; } #endregion }