mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 18:40:50 +08:00 
			
		
		
		
	Add padder widget
This commit adds a padder can be use to pad other IRenderable objects such as tables, panels, grids, text, etc.
This commit is contained in:
		
				
					committed by
					
						
						Patrik Svensson
					
				
			
			
				
	
			
			
			
						parent
						
							314456ca17
						
					
				
				
					commit
					7d6104ace4
				
			@@ -13,7 +13,7 @@ namespace Spectre.Console
 | 
			
		||||
        private readonly List<IRenderable> _items;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        public Padding Padding { get; set; } = new Padding(0, 1);
 | 
			
		||||
        public Padding Padding { get; set; } = new Padding(0, 0, 1, 0);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets a value indicating whether or not the columns should
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ namespace Spectre.Console
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the padding of the column.
 | 
			
		||||
        /// Vertical padding (top and bottom) is ignored.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Padding Padding
 | 
			
		||||
        {
 | 
			
		||||
@@ -48,7 +49,7 @@ namespace Spectre.Console
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public GridColumn()
 | 
			
		||||
        {
 | 
			
		||||
            _padding = new Padding(0, 2);
 | 
			
		||||
            _padding = new Padding(0, 0, 2, 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										106
									
								
								src/Spectre.Console/Widgets/Padder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/Spectre.Console/Widgets/Padder.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Spectre.Console.Internal;
 | 
			
		||||
using Spectre.Console.Rendering;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents padding around a <see cref="IRenderable"/> object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class Padder : Renderable, IPaddable, IExpandable
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IRenderable _child;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        public Padding Padding { get; set; } = new Padding(1, 1, 1, 1);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets a value indicating whether or not the padding should
 | 
			
		||||
        /// fit the available space. If <c>false</c>, the padding width will be
 | 
			
		||||
        /// auto calculated. Defaults to <c>false</c>.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Expand { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="Padder"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="child">The thing to pad.</param>
 | 
			
		||||
        /// <param name="padding">The padding. Defaults to <c>1,1,1,1</c> if null.</param>
 | 
			
		||||
        public Padder(IRenderable child, Padding? padding = null)
 | 
			
		||||
        {
 | 
			
		||||
            _child = child;
 | 
			
		||||
            Padding = padding ?? Padding;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        protected override Measurement Measure(RenderContext context, int maxWidth)
 | 
			
		||||
        {
 | 
			
		||||
            var paddingWidth = Padding.GetWidth();
 | 
			
		||||
            var measurement = _child.Measure(context, maxWidth - paddingWidth);
 | 
			
		||||
 | 
			
		||||
            return new Measurement(
 | 
			
		||||
                measurement.Min + paddingWidth,
 | 
			
		||||
                measurement.Max + paddingWidth);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        protected override IEnumerable<Segment> Render(RenderContext context, int maxWidth)
 | 
			
		||||
        {
 | 
			
		||||
            var paddingWidth = Padding.GetWidth();
 | 
			
		||||
            var childWidth = maxWidth - paddingWidth;
 | 
			
		||||
 | 
			
		||||
            if (!Expand)
 | 
			
		||||
            {
 | 
			
		||||
                var measurement = _child.Measure(context, maxWidth - paddingWidth);
 | 
			
		||||
                childWidth = measurement.Max;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var width = childWidth + paddingWidth;
 | 
			
		||||
            var result = new List<Segment>();
 | 
			
		||||
 | 
			
		||||
            // Top padding
 | 
			
		||||
            for (var i = 0; i < Padding.Top; i++)
 | 
			
		||||
            {
 | 
			
		||||
                result.Add(new Segment(new string(' ', width)));
 | 
			
		||||
                result.Add(Segment.LineBreak);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var child = _child.Render(context, maxWidth - paddingWidth);
 | 
			
		||||
            foreach (var (_, _, _, line) in Segment.SplitLines(child).Enumerate())
 | 
			
		||||
            {
 | 
			
		||||
                // Left padding
 | 
			
		||||
                if (Padding.Left != 0)
 | 
			
		||||
                {
 | 
			
		||||
                    result.Add(new Segment(new string(' ', Padding.Left)));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                result.AddRange(line);
 | 
			
		||||
 | 
			
		||||
                // Right padding
 | 
			
		||||
                if (Padding.Right != 0)
 | 
			
		||||
                {
 | 
			
		||||
                    result.Add(new Segment(new string(' ', Padding.Right)));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Missing space on right side?
 | 
			
		||||
                var lineWidth = line.CellWidth(context.Encoding);
 | 
			
		||||
                var diff = width - lineWidth - Padding.Left - Padding.Right;
 | 
			
		||||
                if (diff > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    result.Add(new Segment(new string(' ', diff)));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                result.Add(Segment.LineBreak);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Bottom padding
 | 
			
		||||
            for (var i = 0; i < Padding.Bottom; i++)
 | 
			
		||||
            {
 | 
			
		||||
                result.Add(new Segment(new string(' ', width)));
 | 
			
		||||
                result.Add(Segment.LineBreak);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -33,7 +33,7 @@ namespace Spectre.Console
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the padding.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Padding Padding { get; set; } = new Padding(1, 1);
 | 
			
		||||
        public Padding Padding { get; set; } = new Padding(1, 0, 1, 0);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the header.
 | 
			
		||||
@@ -61,10 +61,11 @@ namespace Spectre.Console
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        protected override Measurement Measure(RenderContext context, int maxWidth)
 | 
			
		||||
        {
 | 
			
		||||
            var childWidth = _child.Measure(context, maxWidth);
 | 
			
		||||
            var child = new Padder(_child, Padding);
 | 
			
		||||
            var childWidth = ((IRenderable)child).Measure(context, maxWidth);
 | 
			
		||||
            return new Measurement(
 | 
			
		||||
                childWidth.Min + EdgeWidth + Padding.GetHorizontalPadding(),
 | 
			
		||||
                childWidth.Max + EdgeWidth + Padding.GetHorizontalPadding());
 | 
			
		||||
                childWidth.Min + EdgeWidth,
 | 
			
		||||
                childWidth.Max + EdgeWidth);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
@@ -73,16 +74,16 @@ namespace Spectre.Console
 | 
			
		||||
            var border = Border.GetSafeBorder((context.LegacyConsole || !context.Unicode) && UseSafeBorder);
 | 
			
		||||
            var borderStyle = BorderStyle ?? Style.Plain;
 | 
			
		||||
 | 
			
		||||
            var paddingWidth = Padding.GetHorizontalPadding();
 | 
			
		||||
            var childWidth = maxWidth - EdgeWidth - paddingWidth;
 | 
			
		||||
            var child = new Padder(_child, Padding);
 | 
			
		||||
            var childWidth = maxWidth - EdgeWidth;
 | 
			
		||||
 | 
			
		||||
            if (!Expand)
 | 
			
		||||
            {
 | 
			
		||||
                var measurement = _child.Measure(context, maxWidth - EdgeWidth - paddingWidth);
 | 
			
		||||
                var measurement = ((IRenderable)child).Measure(context, maxWidth - EdgeWidth);
 | 
			
		||||
                childWidth = measurement.Max;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var panelWidth = childWidth + EdgeWidth + paddingWidth;
 | 
			
		||||
            var panelWidth = childWidth + EdgeWidth;
 | 
			
		||||
            panelWidth = Math.Min(panelWidth, maxWidth);
 | 
			
		||||
 | 
			
		||||
            var result = new List<Segment>();
 | 
			
		||||
@@ -91,17 +92,11 @@ namespace Spectre.Console
 | 
			
		||||
            AddTopBorder(result, context, border, borderStyle, panelWidth);
 | 
			
		||||
 | 
			
		||||
            // Split the child segments into lines.
 | 
			
		||||
            var childSegments = _child.Render(context, childWidth);
 | 
			
		||||
            var childSegments = ((IRenderable)child).Render(context, childWidth);
 | 
			
		||||
            foreach (var line in Segment.SplitLines(childSegments, panelWidth))
 | 
			
		||||
            {
 | 
			
		||||
                result.Add(new Segment(border.GetPart(BorderPart.CellLeft), borderStyle));
 | 
			
		||||
 | 
			
		||||
                // Left padding
 | 
			
		||||
                if (Padding.Left > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    result.Add(new Segment(new string(' ', Padding.Left)));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var content = new List<Segment>();
 | 
			
		||||
                content.AddRange(line);
 | 
			
		||||
 | 
			
		||||
@@ -115,12 +110,6 @@ namespace Spectre.Console
 | 
			
		||||
 | 
			
		||||
                result.AddRange(content);
 | 
			
		||||
 | 
			
		||||
                // Right padding
 | 
			
		||||
                if (Padding.Right > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    result.Add(new Segment(new string(' ', Padding.Right)));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                result.Add(new Segment(border.GetPart(BorderPart.CellRight), borderStyle));
 | 
			
		||||
                result.Add(Segment.LineBreak);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -221,12 +221,12 @@ namespace Spectre.Console
 | 
			
		||||
                    result.Add(Segment.LineBreak);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Make cells the same shape
 | 
			
		||||
                cells = Segment.MakeSameHeight(cellHeight, cells);
 | 
			
		||||
 | 
			
		||||
                // Iterate through each cell row
 | 
			
		||||
                foreach (var cellRowIndex in Enumerable.Range(0, cellHeight))
 | 
			
		||||
                {
 | 
			
		||||
                    // Make cells the same shape
 | 
			
		||||
                    cells = Segment.MakeSameHeight(cellHeight, cells);
 | 
			
		||||
 | 
			
		||||
                    foreach (var (cellIndex, firstCell, lastCell, cell) in cells.Enumerate())
 | 
			
		||||
                    {
 | 
			
		||||
                        if (firstCell && showBorder)
 | 
			
		||||
@@ -403,7 +403,7 @@ namespace Spectre.Console
 | 
			
		||||
 | 
			
		||||
        private (int Min, int Max) MeasureColumn(TableColumn column, RenderContext options, int maxWidth)
 | 
			
		||||
        {
 | 
			
		||||
            var padding = column.Padding.GetHorizontalPadding();
 | 
			
		||||
            var padding = column.Padding.GetWidth();
 | 
			
		||||
 | 
			
		||||
            // Predetermined width?
 | 
			
		||||
            if (column.Width != null)
 | 
			
		||||
@@ -438,7 +438,7 @@ namespace Spectre.Console
 | 
			
		||||
            var hideBorder = !Border.Visible;
 | 
			
		||||
            var separators = hideBorder ? 0 : _columns.Count - 1;
 | 
			
		||||
            var edges = hideBorder ? 0 : EdgeCount;
 | 
			
		||||
            var padding = includePadding ? _columns.Select(x => x.Padding.GetHorizontalPadding()).Sum() : 0;
 | 
			
		||||
            var padding = includePadding ? _columns.Select(x => x.Padding.GetWidth()).Sum() : 0;
 | 
			
		||||
 | 
			
		||||
            if (!PadRightCell)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ namespace Spectre.Console
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the padding of the column.
 | 
			
		||||
        /// Vertical padding (top and bottom) is ignored.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Padding Padding { get; set; }
 | 
			
		||||
 | 
			
		||||
@@ -52,7 +53,7 @@ namespace Spectre.Console
 | 
			
		||||
        {
 | 
			
		||||
            Text = renderable ?? throw new ArgumentNullException(nameof(renderable));
 | 
			
		||||
            Width = null;
 | 
			
		||||
            Padding = new Padding(1, 1);
 | 
			
		||||
            Padding = new Padding(1, 0, 1, 0);
 | 
			
		||||
            NoWrap = false;
 | 
			
		||||
            Alignment = null;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user