IEnumerable <GridElement> GetRowElements() { var rowLength = 0; while (ChildrenQueue.Any()) { var element = ChildrenQueue.Peek(); if (rowLength + element.Columns > ColumnsCount) { break; } rowLength += element.Columns; yield return(ChildrenQueue.Dequeue()); } }
internal override SpacePlan Measure(Size availableSpace) { if (!ChildrenQueue.Any()) { return(SpacePlan.FullRender(Size.Zero)); } var lines = Compose(availableSpace); if (!lines.Any()) { return(SpacePlan.Wrap()); } var lineSizes = lines .Select(line => { var size = GetLineSize(line); var widthWithSpacing = size.Width + (line.Count - 1) * HorizontalSpacing; return(new Size(widthWithSpacing, size.Height)); }) .ToList(); var width = lineSizes.Max(x => x.Width); var height = lineSizes.Sum(x => x.Height) + (lines.Count - 1) * VerticalSpacing; var targetSize = new Size(width, height); var isPartiallyRendered = lines.Sum(x => x.Count) != ChildrenQueue.Count; if (isPartiallyRendered) { return(SpacePlan.PartialRender(targetSize)); } return(SpacePlan.FullRender(targetSize)); }
internal override void Draw(Size availableSpace) { var lines = Compose(availableSpace); var topOffset = 0f; foreach (var line in lines) { var height = line .Select(x => x.Measure(Size.Max)) .Where(x => x.Type != SpacePlanType.Wrap) .Max(x => x.Height); DrawLine(line); topOffset += height + VerticalSpacing; Canvas.Translate(new Position(0, height + VerticalSpacing)); } Canvas.Translate(new Position(0, -topOffset)); lines.SelectMany(x => x).ToList().ForEach(x => ChildrenQueue.Dequeue()); void DrawLine(ICollection <InlinedElement> elements) { var lineSize = GetLineSize(elements); var elementOffset = ElementOffset(); var leftOffset = AlignOffset(); Canvas.Translate(new Position(leftOffset, 0)); foreach (var element in elements) { var size = (Size)element.Measure(Size.Max); var baselineOffset = BaselineOffset(size, lineSize.Height); if (size.Height == 0) { size = new Size(size.Width, lineSize.Height); } Canvas.Translate(new Position(0, baselineOffset)); element.Draw(size); Canvas.Translate(new Position(0, -baselineOffset)); leftOffset += size.Width + elementOffset; Canvas.Translate(new Position(size.Width + elementOffset, 0)); } Canvas.Translate(new Position(-leftOffset, 0)); float ElementOffset() { var difference = availableSpace.Width - lineSize.Width; if (elements.Count == 1) { return(0); } return(ElementsAlignment switch { InlinedAlignment.Justify => difference / (elements.Count - 1), InlinedAlignment.SpaceAround => difference / (elements.Count + 1), _ => HorizontalSpacing }); } float AlignOffset() { var difference = availableSpace.Width - lineSize.Width - (elements.Count - 1) * HorizontalSpacing; return(ElementsAlignment switch { InlinedAlignment.Left => 0, InlinedAlignment.Justify => 0, InlinedAlignment.SpaceAround => elementOffset, InlinedAlignment.Center => difference / 2, InlinedAlignment.Right => difference, _ => 0 }); }