using System.Collections.Generic; using Spectre.Console.Rendering; namespace Spectre.Console { /// /// Represents padding around a object. /// public sealed class Padder : Renderable, IPaddable, IExpandable { private readonly IRenderable _child; /// public Padding? Padding { get; set; } = new Padding(1, 1, 1, 1); /// /// Gets or sets a value indicating whether or not the padding should /// fit the available space. If false, the padding width will be /// auto calculated. Defaults to false. /// public bool Expand { get; set; } /// /// Initializes a new instance of the class. /// /// The thing to pad. /// The padding. Defaults to 1,1,1,1 if null. public Padder(IRenderable child, Padding? padding = null) { _child = child; Padding = padding ?? Padding; } /// protected override Measurement Measure(RenderContext context, int maxWidth) { var paddingWidth = Padding?.GetWidth() ?? 0; var measurement = _child.Measure(context, maxWidth - paddingWidth); return new Measurement( measurement.Min + paddingWidth, measurement.Max + paddingWidth); } /// protected override IEnumerable Render(RenderContext context, int maxWidth) { var paddingWidth = Padding?.GetWidth() ?? 0; var childWidth = maxWidth - paddingWidth; if (!Expand) { var measurement = _child.Measure(context, maxWidth - paddingWidth); childWidth = measurement.Max; } var width = childWidth + paddingWidth; var result = new List(); if (width > maxWidth) { width = maxWidth; } // Top padding for (var i = 0; i < Padding.GetTopSafe(); i++) { result.Add(Segment.Padding(width)); result.Add(Segment.LineBreak); } var child = _child.Render(context, maxWidth - paddingWidth); foreach (var line in Segment.SplitLines(child)) { // Left padding if (Padding.GetLeftSafe() != 0) { result.Add(Segment.Padding(Padding.GetLeftSafe())); } result.AddRange(line); // Right padding if (Padding.GetRightSafe() != 0) { result.Add(Segment.Padding(Padding.GetRightSafe())); } // Missing space on right side? var lineWidth = line.CellCount(); var diff = width - lineWidth - Padding.GetLeftSafe() - Padding.GetRightSafe(); if (diff > 0) { result.Add(Segment.Padding(diff)); } result.Add(Segment.LineBreak); } // Bottom padding for (var i = 0; i < Padding.GetBottomSafe(); i++) { result.Add(Segment.Padding(width)); result.Add(Segment.LineBreak); } return result; } } }