public DiffViewPort(IEnumerable <IChildViewPort> leftChildren, IEnumerable <IChildViewPort> rightChildren) { left = leftChildren.ToList(); right = rightChildren.ToList(); EqualizeScroll(left, right); Debug.Assert(left.Count == right.Count, "Diff views must have the same number of diff elements on each side!"); // combine similar children for (int i = 0; i < left.Count - 1; i++) { if (CompositeChildViewPort.TryCombine(left[i], left[i + 1], out var leftResult) && CompositeChildViewPort.TryCombine(right[i], right[i + 1], out var rightResult)) { left[i] = leftResult; right[i] = rightResult; left.RemoveAt(i + 1); right.RemoveAt(i + 1); i -= 1; } } leftWidth = left.Count == 0 ? 16 : Math.Min(MaxInnerTabWidth, left.Max(child => child.Width)); rightWidth = right.Count == 0 ? 16 : Math.Min(MaxInnerTabWidth, right.Max(child => child.Width)); startOfNextSegment = new List <int>(); startOfNextSegment.Add(0); for (int i = 0; i < Math.Min(left.Count, right.Count); i++) { startOfNextSegment.Add(startOfNextSegment[i] + 1 + Math.Max(left[i].Height, right[i].Height)); } }
public static bool TryCombine(IChildViewPort a, IChildViewPort b, out CompositeChildViewPort result) { result = null; if (b is CompositeChildViewPort) { return(false); } result = a is CompositeChildViewPort composite ? composite : new CompositeChildViewPort { a }; if (a.Parent != b.Parent) { return(false); } if (a.Width != b.Width) { return(false); } if (b.DataOffset < a.DataOffset) { return(false); } if ((b.DataOffset - a.DataOffset) % b.Width != 0) { return(false); } var bSelectionLine = (GetFirstVisibleSelectedAddress(b) - a.DataOffset) / b.Width; var aSelectionLine = (GetLastVisibleSelectedAddress(a) - a.DataOffset) / b.Width; var lineDif = bSelectionLine - aSelectionLine; if (lineDif > 3) { return(false); } a.Height += lineDif; b.ScrollValue -= (b.DataOffset - a.DataOffset) / b.Width; b.Height = a.Height; Debug.Assert(a.DataOffset == b.DataOffset, "Data Offsets should be the same at this point!"); result.Add(b); return(true); }