diff --git a/src/LiveSplit.Splits/UI/ColumnType.cs b/src/LiveSplit.Splits/UI/ColumnType.cs index 07def45..9ea1e6b 100644 --- a/src/LiveSplit.Splits/UI/ColumnType.cs +++ b/src/LiveSplit.Splits/UI/ColumnType.cs @@ -2,5 +2,5 @@ public enum ColumnType { - Delta, SplitTime, DeltaorSplitTime, SegmentDelta, SegmentTime, SegmentDeltaorSegmentTime + Delta, SplitTime, DeltaorSplitTime, SegmentDelta, SegmentTime, SegmentDeltaorSegmentTime, CustomVariable } diff --git a/src/LiveSplit.Splits/UI/Components/ColumnSettings.Designer.cs b/src/LiveSplit.Splits/UI/Components/ColumnSettings.Designer.cs index 5c3a4d7..36aab24 100644 --- a/src/LiveSplit.Splits/UI/Components/ColumnSettings.Designer.cs +++ b/src/LiveSplit.Splits/UI/Components/ColumnSettings.Designer.cs @@ -137,7 +137,8 @@ private void InitializeComponent() "Delta or Split Time", "Segment Delta", "Segment Time", - "Segment Delta or Segment Time"}); + "Segment Delta or Segment Time", + "Custom Variable"}); this.cmbColumnType.Location = new System.Drawing.Point(93, 33); this.cmbColumnType.Name = "cmbColumnType"; this.cmbColumnType.Size = new System.Drawing.Size(325, 21); @@ -247,4 +248,4 @@ private void InitializeComponent() private System.Windows.Forms.Button btnMoveDown; private System.Windows.Forms.Button btnMoveUp; } -} \ No newline at end of file +} diff --git a/src/LiveSplit.Splits/UI/Components/ColumnSettings.cs b/src/LiveSplit.Splits/UI/Components/ColumnSettings.cs index deda8ef..a33cb0b 100644 --- a/src/LiveSplit.Splits/UI/Components/ColumnSettings.cs +++ b/src/LiveSplit.Splits/UI/Components/ColumnSettings.cs @@ -131,10 +131,18 @@ private static string GetColumnType(ColumnType type) { return "Segment Delta"; } - else + else if (type == ColumnType.SegmentDeltaorSegmentTime) { return "Segment Delta or Segment Time"; } + else if (type == ColumnType.CustomVariable) + { + return "Custom Variable"; + } + else + { + return "Unknown"; + } } private static ColumnType ParseColumnType(string columnType) diff --git a/src/LiveSplit.Splits/UI/Components/LabelsComponent.cs b/src/LiveSplit.Splits/UI/Components/LabelsComponent.cs index 5b594ea..d1da35c 100644 --- a/src/LiveSplit.Splits/UI/Components/LabelsComponent.cs +++ b/src/LiveSplit.Splits/UI/Components/LabelsComponent.cs @@ -6,7 +6,6 @@ using LiveSplit.Model; using LiveSplit.Model.Comparisons; -using LiveSplit.TimeFormatters; namespace LiveSplit.UI.Components; @@ -14,22 +13,13 @@ public class LabelsComponent : IComponent { public SplitsSettings Settings { get; set; } - protected SimpleLabel MeasureTimeLabel { get; set; } - protected SimpleLabel MeasureDeltaLabel { get; set; } - - protected ITimeFormatter TimeFormatter { get; set; } - protected ITimeFormatter DeltaTimeFormatter { get; set; } - - protected TimeAccuracy CurrentAccuracy { get; set; } - protected TimeAccuracy CurrentDeltaAccuracy { get; set; } - protected bool CurrentDropDecimals { get; set; } - protected int FrameCount { get; set; } public GraphicsCache Cache { get; set; } public IEnumerable ColumnsList { get; set; } public IList LabelsList { get; set; } + protected List<(int exLength, float exWidth, float width)> ColumnWidths { get; } public float PaddingTop => 0f; public float PaddingLeft => 0f; @@ -45,19 +35,15 @@ public class LabelsComponent : IComponent public float MinimumHeight { get; set; } public IDictionary ContextMenuControls => null; - public LabelsComponent(SplitsSettings settings, IEnumerable columns) + public LabelsComponent(SplitsSettings settings, IEnumerable columns, List<(int exLength, float exWidth, float width)> columnWidths) { Settings = settings; MinimumHeight = 31; - MeasureTimeLabel = new SimpleLabel(); - MeasureDeltaLabel = new SimpleLabel(); - TimeFormatter = new SplitTimeFormatter(Settings.SplitTimesAccuracy); - DeltaTimeFormatter = new DeltaSplitTimeFormatter(Settings.DeltasAccuracy, Settings.DropDecimals); - Cache = new GraphicsCache(); LabelsList = []; ColumnsList = columns; + ColumnWidths = columnWidths; } private void DrawGeneral(Graphics g, LiveSplitState state, float width, float height, LayoutMode mode) @@ -69,30 +55,6 @@ private void DrawGeneral(Graphics g, LiveSplitState state, float width, float he ), 0, 0, width, height); } - MeasureTimeLabel.Text = TimeFormatter.Format(new TimeSpan(24, 0, 0)); - MeasureDeltaLabel.Text = DeltaTimeFormatter.Format(new TimeSpan(0, 9, 0, 0)); - - MeasureTimeLabel.Font = state.LayoutSettings.TimesFont; - MeasureTimeLabel.IsMonospaced = true; - MeasureDeltaLabel.Font = state.LayoutSettings.TimesFont; - MeasureDeltaLabel.IsMonospaced = true; - - MeasureTimeLabel.SetActualWidth(g); - MeasureDeltaLabel.SetActualWidth(g); - - if (Settings.SplitTimesAccuracy != CurrentAccuracy) - { - TimeFormatter = new SplitTimeFormatter(Settings.SplitTimesAccuracy); - CurrentAccuracy = Settings.SplitTimesAccuracy; - } - - if (Settings.DeltasAccuracy != CurrentDeltaAccuracy || Settings.DropDecimals != CurrentDropDecimals) - { - DeltaTimeFormatter = new DeltaSplitTimeFormatter(Settings.DeltasAccuracy, Settings.DropDecimals); - CurrentDeltaAccuracy = Settings.DeltasAccuracy; - CurrentDropDecimals = Settings.DropDecimals; - } - foreach (SimpleLabel label in LabelsList) { label.ShadowColor = state.LayoutSettings.ShadowsColor; @@ -105,24 +67,15 @@ private void DrawGeneral(Graphics g, LiveSplitState state, float width, float he if (ColumnsList.Count() == LabelsList.Count) { + while (ColumnWidths.Count < LabelsList.Count) + { + ColumnWidths.Add((0, 0f, 0f)); + } + float curX = width - 7; foreach (SimpleLabel label in LabelsList.Reverse()) { - ColumnData column = ColumnsList.ElementAt(LabelsList.IndexOf(label)); - - float labelWidth = 0f; - if (column.Type is ColumnType.DeltaorSplitTime or ColumnType.SegmentDeltaorSegmentTime) - { - labelWidth = Math.Max(MeasureDeltaLabel.ActualWidth, MeasureTimeLabel.ActualWidth); - } - else if (column.Type is ColumnType.Delta or ColumnType.SegmentDelta) - { - labelWidth = MeasureDeltaLabel.ActualWidth; - } - else - { - labelWidth = MeasureTimeLabel.ActualWidth; - } + float labelWidth = ColumnWidths[LabelsList.IndexOf(label)].width; curX -= labelWidth + 5; label.Width = labelWidth; @@ -212,9 +165,14 @@ public void Update(IInvalidator invalidator, LiveSplitState state, float width, Cache.Restart(); Cache["ColumnsCount"] = ColumnsList.Count(); - foreach (SimpleLabel label in LabelsList) + for (int index = 0; index < LabelsList.Count; index++) { - Cache["Columns" + LabelsList.IndexOf(label) + "Text"] = label.Text; + SimpleLabel label = LabelsList[index]; + Cache["Columns" + index + "Text"] = label.Text; + if (index < ColumnWidths.Count) + { + Cache["Columns" + index + "Width"] = ColumnWidths[index].width; + } } if (invalidator != null && (Cache.HasChanged || FrameCount > 1)) diff --git a/src/LiveSplit.Splits/UI/Components/SplitComponent.cs b/src/LiveSplit.Splits/UI/Components/SplitComponent.cs index a0240ac..fda4c8e 100644 --- a/src/LiveSplit.Splits/UI/Components/SplitComponent.cs +++ b/src/LiveSplit.Splits/UI/Components/SplitComponent.cs @@ -16,8 +16,6 @@ public class SplitComponent : IComponent public ISegment Split { get; set; } protected SimpleLabel NameLabel { get; set; } - protected SimpleLabel MeasureTimeLabel { get; set; } - protected SimpleLabel MeasureDeltaLabel { get; set; } public SplitsSettings Settings { get; set; } protected int FrameCount { get; set; } @@ -47,6 +45,7 @@ public class SplitComponent : IComponent public IEnumerable ColumnsList { get; set; } public IList LabelsList { get; set; } + protected List<(int exLength, float exWidth, float width)> ColumnWidths { get; } public float VerticalHeight { get; set; } @@ -60,17 +59,16 @@ public float HorizontalWidth public IDictionary ContextMenuControls => null; - public SplitComponent(SplitsSettings settings, IEnumerable columnsList) + public SplitComponent(SplitsSettings settings, IEnumerable columnsList, List<(int exLength, float exWidth, float width)> columnWidths) { NameLabel = new SimpleLabel() { HorizontalAlignment = StringAlignment.Near, X = 8, }; - MeasureTimeLabel = new SimpleLabel(); - MeasureDeltaLabel = new SimpleLabel(); Settings = settings; ColumnsList = columnsList; + ColumnWidths = columnWidths; TimeFormatter = new SplitTimeFormatter(Settings.SplitTimesAccuracy); DeltaTimeFormatter = new DeltaSplitTimeFormatter(Settings.DeltasAccuracy, Settings.DropDecimals); MinimumHeight = 25; @@ -99,17 +97,6 @@ private void DrawGeneral(Graphics g, LiveSplitState state, float width, float he ), 0, 0, width, height); } - MeasureTimeLabel.Text = TimeFormatter.Format(new TimeSpan(24, 0, 0)); - MeasureDeltaLabel.Text = DeltaTimeFormatter.Format(new TimeSpan(0, 9, 0, 0)); - - MeasureTimeLabel.Font = state.LayoutSettings.TimesFont; - MeasureTimeLabel.IsMonospaced = true; - MeasureDeltaLabel.Font = state.LayoutSettings.TimesFont; - MeasureDeltaLabel.IsMonospaced = true; - - MeasureTimeLabel.SetActualWidth(g); - MeasureDeltaLabel.SetActualWidth(g); - NameLabel.ShadowColor = state.LayoutSettings.ShadowsColor; NameLabel.OutlineColor = state.LayoutSettings.TextOutlineColor; foreach (SimpleLabel label in LabelsList) @@ -229,25 +216,17 @@ private void DrawGeneral(Graphics g, LiveSplitState state, float width, float he if (ColumnsList.Count() == LabelsList.Count) { + while (ColumnWidths.Count < LabelsList.Count) + { + ColumnWidths.Add((0, 0f, 0f)); + } + float curX = width - 7; float nameX = width - 7; foreach (SimpleLabel label in LabelsList.Reverse()) { - ColumnData column = ColumnsList.ElementAt(LabelsList.IndexOf(label)); - - float labelWidth = 0f; - if (column.Type is ColumnType.DeltaorSplitTime or ColumnType.SegmentDeltaorSegmentTime) - { - labelWidth = Math.Max(MeasureDeltaLabel.ActualWidth, MeasureTimeLabel.ActualWidth); - } - else if (column.Type is ColumnType.Delta or ColumnType.SegmentDelta) - { - labelWidth = MeasureDeltaLabel.ActualWidth; - } - else - { - labelWidth = MeasureTimeLabel.ActualWidth; - } + int i = LabelsList.IndexOf(label); + float labelWidth = ColumnWidths[i].width; label.Width = labelWidth + 20; curX -= labelWidth + 5; @@ -261,6 +240,10 @@ private void DrawGeneral(Graphics g, LiveSplitState state, float width, float he if (!string.IsNullOrEmpty(label.Text)) { nameX = curX + labelWidth + 5 - label.ActualWidth; + if (ColumnWidths[i].exWidth < label.ActualWidth) + { + ColumnWidths[i] = (label.Text.Length, label.ActualWidth, labelWidth); + } } } @@ -387,7 +370,7 @@ protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData int splitIndex = state.Run.IndexOf(Split); if (splitIndex < state.CurrentSplitIndex) { - if (type is ColumnType.SplitTime or ColumnType.SegmentTime) + if (type is ColumnType.SplitTime or ColumnType.SegmentTime or ColumnType.CustomVariable) { label.ForeColor = Settings.OverrideTimesColor ? Settings.BeforeTimesColor : state.LayoutSettings.TextColor; @@ -395,11 +378,16 @@ protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData { label.Text = TimeFormatter.Format(Split.SplitTime[timingMethod]); } - else //SegmentTime + else if (type == ColumnType.SegmentTime) { TimeSpan? segmentTime = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, timingMethod); label.Text = TimeFormatter.Format(segmentTime); } + else if (type == ColumnType.CustomVariable) + { + Split.CustomVariableValues.TryGetValue(data.Name, out string text); + label.Text = text ?? ""; + } } if (type is ColumnType.DeltaorSplitTime or ColumnType.Delta) @@ -461,7 +449,7 @@ protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData } else { - if (type is ColumnType.SplitTime or ColumnType.SegmentTime or ColumnType.DeltaorSplitTime or ColumnType.SegmentDeltaorSegmentTime) + if (type is ColumnType.SplitTime or ColumnType.SegmentTime or ColumnType.DeltaorSplitTime or ColumnType.SegmentDeltaorSegmentTime or ColumnType.CustomVariable) { if (Split == state.CurrentSplit) { @@ -476,7 +464,7 @@ protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData { label.Text = TimeFormatter.Format(Split.Comparisons[comparison][timingMethod]); } - else //SegmentTime or SegmentTimeorSegmentDeltaTime + else if (type is ColumnType.SegmentTime or ColumnType.SegmentDeltaorSegmentTime) { TimeSpan previousTime = TimeSpan.Zero; for (int index = splitIndex - 1; index >= 0; index--) @@ -491,6 +479,17 @@ protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData label.Text = TimeFormatter.Format(Split.Comparisons[comparison][timingMethod] - previousTime); } + else if (type is ColumnType.CustomVariable) + { + if (splitIndex == state.CurrentSplitIndex) + { + label.Text = state.Run.Metadata.CustomVariableValue(data.Name) ?? ""; + } + else if (splitIndex > state.CurrentSplitIndex) + { + label.Text = ""; + } + } } //Live Delta @@ -511,14 +510,9 @@ protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData protected float CalculateLabelsWidth() { - if (ColumnsList != null) + if (ColumnWidths != null) { - int mixedCount = ColumnsList.Count(x => x.Type is ColumnType.DeltaorSplitTime or ColumnType.SegmentDeltaorSegmentTime); - int deltaCount = ColumnsList.Count(x => x.Type is ColumnType.Delta or ColumnType.SegmentDelta); - int timeCount = ColumnsList.Count(x => x.Type is ColumnType.SplitTime or ColumnType.SegmentTime); - return (mixedCount * (Math.Max(MeasureDeltaLabel.ActualWidth, MeasureTimeLabel.ActualWidth) + 5)) - + (deltaCount * (MeasureDeltaLabel.ActualWidth + 5)) - + (timeCount * (MeasureTimeLabel.ActualWidth + 5)); + return ColumnWidths.Sum(e => e.width) + (5 * ColumnWidths.Count()); } return 0f; @@ -569,10 +563,15 @@ public void Update(IInvalidator invalidator, LiveSplitState state, float width, Cache["IsActive"] = IsActive; Cache["NameColor"] = NameLabel.ForeColor.ToArgb(); Cache["ColumnsCount"] = ColumnsList.Count(); - foreach (SimpleLabel label in LabelsList) + for (int index = 0; index < LabelsList.Count; index++) { - Cache["Columns" + LabelsList.IndexOf(label) + "Text"] = label.Text; - Cache["Columns" + LabelsList.IndexOf(label) + "Color"] = label.ForeColor.ToArgb(); + SimpleLabel label = LabelsList[index]; + Cache["Columns" + index + "Text"] = label.Text; + Cache["Columns" + index + "Color"] = label.ForeColor.ToArgb(); + if (index < ColumnWidths.Count) + { + Cache["Columns" + index + "Width"] = ColumnWidths[index].width; + } } if (invalidator != null && (Cache.HasChanged || FrameCount > 1)) diff --git a/src/LiveSplit.Splits/UI/Components/SplitsComponent.cs b/src/LiveSplit.Splits/UI/Components/SplitsComponent.cs index 0e8b72d..b2d65db 100644 --- a/src/LiveSplit.Splits/UI/Components/SplitsComponent.cs +++ b/src/LiveSplit.Splits/UI/Components/SplitsComponent.cs @@ -6,6 +6,7 @@ using System.Windows.Forms; using LiveSplit.Model; +using LiveSplit.TimeFormatters; namespace LiveSplit.UI.Components; @@ -23,6 +24,17 @@ public class SplitsComponent : IComponent protected SplitsSettings Settings { get; set; } + protected SimpleLabel MeasureTimeLabel { get; set; } + protected SimpleLabel MeasureDeltaLabel { get; set; } + protected SimpleLabel MeasureCharLabel { get; set; } + + protected TimeAccuracy CurrentAccuracy { get; set; } + protected TimeAccuracy CurrentDeltaAccuracy { get; set; } + protected bool CurrentDropDecimals { get; set; } + + protected ITimeFormatter TimeFormatter { get; set; } + protected ITimeFormatter DeltaTimeFormatter { get; set; } + private Dictionary ShadowImages { get; set; } private int visualSplitCount; @@ -39,6 +51,7 @@ public class SplitsComponent : IComponent protected Color OldShadowsColor { get; set; } protected IEnumerable ColumnsList => Settings.ColumnsList.Select(x => x.Data); + protected List<(int exLength, float exWidth, float width)> ColumnWidths { get; set; } public string ComponentName => "Splits"; @@ -57,10 +70,21 @@ public SplitsComponent(LiveSplitState state) CurrentState = state; Settings = new SplitsSettings(state); InternalComponent = new ComponentRendererComponent(); + + MeasureTimeLabel = new SimpleLabel(); + MeasureDeltaLabel = new SimpleLabel(); + MeasureCharLabel = new SimpleLabel(); + CurrentAccuracy = Settings.SplitTimesAccuracy; + CurrentDeltaAccuracy = Settings.DeltasAccuracy; + CurrentDropDecimals = Settings.DropDecimals; + TimeFormatter = new SplitTimeFormatter(CurrentAccuracy); + DeltaTimeFormatter = new DeltaSplitTimeFormatter(CurrentDeltaAccuracy, CurrentDropDecimals); + ShadowImages = []; visualSplitCount = Settings.VisualSplitCount; settingsSplitCount = Settings.VisualSplitCount; Settings.SplitLayoutChanged += Settings_SplitLayoutChanged; + ColumnWidths = Settings.ColumnsList.Select(_ => (0, 0f, 0f)).ToList(); ScrollOffset = 0; RebuildVisualSplits(); state.ComparisonRenamed += state_ComparisonRenamed; @@ -94,7 +118,7 @@ private void RebuildVisualSplits() if (Settings.ShowColumnLabels && CurrentState.Layout?.Mode == LayoutMode.Vertical) { - Components.Add(new LabelsComponent(Settings, ColumnsList)); + Components.Add(new LabelsComponent(Settings, ColumnsList, ColumnWidths)); Components.Add(new SeparatorComponent()); } @@ -113,7 +137,7 @@ private void RebuildVisualSplits() } } - var splitComponent = new SplitComponent(Settings, ColumnsList); + var splitComponent = new SplitComponent(Settings, ColumnsList, ColumnWidths); Components.Add(splitComponent); if (i < visualSplitCount - 1 || i == (Settings.LockLastSplit ? totalSplits - 1 : visualSplitCount - 1)) { @@ -141,6 +165,19 @@ private void Prepare(LiveSplitState state) OldState = state; } + if (Settings.SplitTimesAccuracy != CurrentAccuracy) + { + TimeFormatter = new SplitTimeFormatter(Settings.SplitTimesAccuracy); + CurrentAccuracy = Settings.SplitTimesAccuracy; + } + + if (Settings.DeltasAccuracy != CurrentDeltaAccuracy || Settings.DropDecimals != CurrentDropDecimals) + { + DeltaTimeFormatter = new DeltaSplitTimeFormatter(Settings.DeltasAccuracy, Settings.DropDecimals); + CurrentDeltaAccuracy = Settings.DeltasAccuracy; + CurrentDropDecimals = Settings.DropDecimals; + } + int previousSplitCount = visualSplitCount; visualSplitCount = Math.Min(state.Run.Count, Settings.VisualSplitCount); if (previousSplitCount != visualSplitCount @@ -305,10 +342,29 @@ private void DrawBackground(Graphics g, float width, float height) } } + private void SetMeasureLabels(Graphics g, LiveSplitState state) + { + MeasureTimeLabel.Text = TimeFormatter.Format(new TimeSpan(24, 0, 0)); + MeasureDeltaLabel.Text = DeltaTimeFormatter.Format(new TimeSpan(0, 9, 0, 0)); + MeasureCharLabel.Text = "W"; + + MeasureTimeLabel.Font = state.LayoutSettings.TimesFont; + MeasureTimeLabel.IsMonospaced = true; + MeasureDeltaLabel.Font = state.LayoutSettings.TimesFont; + MeasureDeltaLabel.IsMonospaced = true; + MeasureCharLabel.Font = state.LayoutSettings.TimesFont; + MeasureCharLabel.IsMonospaced = true; + + MeasureTimeLabel.SetActualWidth(g); + MeasureDeltaLabel.SetActualWidth(g); + MeasureCharLabel.SetActualWidth(g); + } + public void DrawVertical(Graphics g, LiveSplitState state, float width, Region clipRegion) { Prepare(state); DrawBackground(g, width, VerticalHeight); + SetMeasureLabels(g, state); InternalComponent.DrawVertical(g, state, width, clipRegion); } @@ -316,6 +372,7 @@ public void DrawHorizontal(Graphics g, LiveSplitState state, float height, Regio { Prepare(state); DrawBackground(g, HorizontalWidth, height); + SetMeasureLabels(g, state); InternalComponent.DrawHorizontal(g, state, height, clipRegion); } @@ -361,12 +418,96 @@ public void Update(IInvalidator invalidator, LiveSplitState state, float width, } } + CalculateColumnWidths(state.Run); + if (invalidator != null) { InternalComponent.Update(invalidator, state, width, height, mode); } } + private void CalculateColumnWidths(IRun run) + { + if (ColumnsList != null) + { + while (ColumnWidths.Count < ColumnsList.Count()) + { + ColumnWidths.Add((0, 0f, 0f)); + } + + TimeSpan longestTime = new TimeSpan(9, 0, 0); + TimeSpan longestDelta = new TimeSpan(0, 0, 59, 0); + foreach (ISegment split in run.Reverse()) + { + if (split.SplitTime.RealTime is TimeSpan splitRealTime && longestTime < splitRealTime) + { + longestTime = splitRealTime; + } + + foreach (KeyValuePair kv in split.Comparisons) + { + if (kv.Value.RealTime is TimeSpan cmpRealTime && longestTime < cmpRealTime) + { + longestTime = cmpRealTime; + } + + if (split.SplitTime.RealTime - kv.Value.RealTime is TimeSpan deltaRealTime) + { + if (longestDelta < deltaRealTime) + { + longestDelta = deltaRealTime; + } + else if (longestDelta < (- deltaRealTime)) + { + longestDelta = - deltaRealTime; + } + } + } + } + + int timeLength = TimeFormatter.Format(longestTime).Length; + int deltaLength = DeltaTimeFormatter.Format(longestDelta).Length; + float timeCharWidth = MeasureTimeLabel.Text.Length > 0 ? MeasureTimeLabel.ActualWidth / MeasureTimeLabel.Text.Length : MeasureCharLabel.ActualWidth; + float timeWidth = Math.Max(MeasureTimeLabel.ActualWidth, timeCharWidth * (timeLength + 1)); + float deltaWidth = Math.Max(MeasureDeltaLabel.ActualWidth, timeCharWidth * (deltaLength + 1)); + + for (int i = 0; i < ColumnsList.Count(); i++) + { + ColumnData column = ColumnsList.ElementAt(i); + + float labelWidth = 0f; + if (column.Type is ColumnType.DeltaorSplitTime or ColumnType.SegmentDeltaorSegmentTime) + { + labelWidth = Math.Max(deltaWidth, timeWidth); + } + else if (column.Type is ColumnType.Delta or ColumnType.SegmentDelta) + { + labelWidth = deltaWidth; + } + else if (column.Type is ColumnType.SplitTime or ColumnType.SegmentTime) + { + labelWidth = timeWidth; + } + else if (column.Type is ColumnType.CustomVariable) + { + int longestLength = run.Metadata.CustomVariableValue(column.Name).Length; + foreach (ISegment split in run) + { + if (split.CustomVariableValues.TryGetValue(column.Name, out string value) && !string.IsNullOrEmpty(value)) + { + longestLength = Math.Max(longestLength, value.Length); + } + } + + float exCharWidth = ColumnWidths[i].exLength > 0 ? ColumnWidths[i].exWidth / ColumnWidths[i].exLength : MeasureCharLabel.ActualWidth; + labelWidth = exCharWidth * (longestLength + 1); + } + + ColumnWidths[i] = (ColumnWidths[i].exLength, ColumnWidths[i].exWidth, labelWidth); + } + } + } + public void Dispose() { }