mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00

committed by
Patrik Svensson

parent
5c119ee0c3
commit
cb2924a609
@ -79,5 +79,22 @@ namespace Spectre.Console
|
||||
calendar.HightlightStyle = style ?? Style.Plain;
|
||||
return calendar;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the calendar's header <see cref="Style"/>.
|
||||
/// </summary>
|
||||
/// <param name="calendar">The calendar.</param>
|
||||
/// <param name="style">The header style.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Calendar SetHeaderStyle(this Calendar calendar, Style? style)
|
||||
{
|
||||
if (calendar is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(calendar));
|
||||
}
|
||||
|
||||
calendar.HeaderStyle = style ?? Style.Plain;
|
||||
return calendar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ namespace Spectre.Console
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
return SetHeader(panel, new PanelHeader(text, style, alignment));
|
||||
return SetHeader(panel, new Title(text, style, alignment));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -36,7 +36,7 @@ namespace Spectre.Console
|
||||
/// <param name="panel">The panel.</param>
|
||||
/// <param name="header">The header to use.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Panel SetHeader(this Panel panel, PanelHeader header)
|
||||
public static Panel SetHeader(this Panel panel, Title header)
|
||||
{
|
||||
if (panel is null)
|
||||
{
|
||||
|
@ -176,5 +176,85 @@ namespace Spectre.Console
|
||||
table.ShowHeaders = false;
|
||||
return table;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the table heading.
|
||||
/// </summary>
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="text">The heading.</param>
|
||||
/// <param name="style">The style.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetHeading(this Table table, string text, Style? style = null, Justify? alignment = null)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
if (text is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
return SetHeading(table, new Title(text, style, alignment));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the table heading.
|
||||
/// </summary>
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="heading">The heading.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetHeading(this Table table, Title heading)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
table.Heading = heading;
|
||||
return table;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the table footnote.
|
||||
/// </summary>
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="text">The footnote.</param>
|
||||
/// <param name="style">The style.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetFootnote(this Table table, string text, Style? style = null, Justify? alignment = null)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
if (text is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
}
|
||||
|
||||
return SetFootnote(table, new Title(text, style, alignment));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the table footnote.
|
||||
/// </summary>
|
||||
/// <param name="table">The table.</param>
|
||||
/// <param name="footnote">The footnote.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public static Table SetFootnote(this Table table, Title footnote)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
table.Footnote = footnote;
|
||||
return table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,9 @@ namespace Spectre.Console.Internal
|
||||
public static string GetAbbreviatedDayName(this DayOfWeek day, CultureInfo culture)
|
||||
{
|
||||
culture ??= CultureInfo.InvariantCulture;
|
||||
var name = culture.DateTimeFormat.GetAbbreviatedDayName(day);
|
||||
|
||||
if (name.Length > 0 && char.IsLower(name[0]))
|
||||
{
|
||||
name = string.Format(culture, "{0}{1}", char.ToUpper(name[0], culture), name.Substring(1));
|
||||
}
|
||||
|
||||
return name;
|
||||
return culture.DateTimeFormat
|
||||
.GetAbbreviatedDayName(day)
|
||||
.Capitalize(culture);
|
||||
}
|
||||
|
||||
public static DayOfWeek GetNextWeekDay(this DayOfWeek day)
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
@ -18,6 +19,23 @@ namespace Spectre.Console.Internal
|
||||
return Cell.GetCellLength(context, text);
|
||||
}
|
||||
|
||||
public static string Capitalize(this string text, CultureInfo? culture = null)
|
||||
{
|
||||
if (text == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
culture ??= CultureInfo.InvariantCulture;
|
||||
|
||||
if (text.Length > 0 && char.IsLower(text[0]))
|
||||
{
|
||||
text = string.Format(culture, "{0}{1}", char.ToUpper(text[0], culture), text.Substring(1));
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public static string NormalizeLineEndings(this string text, bool native = false)
|
||||
{
|
||||
text ??= string.Empty;
|
||||
|
@ -28,6 +28,8 @@ namespace Spectre.Console
|
||||
private bool _dirty;
|
||||
private CultureInfo _culture;
|
||||
private Style _highlightStyle;
|
||||
private bool _showHeader;
|
||||
private Style? _headerStyle;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the calendar year.
|
||||
@ -95,6 +97,24 @@ namespace Spectre.Console
|
||||
set => MarkAsDirty(() => _highlightStyle = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not the calendar header should be shown.
|
||||
/// </summary>
|
||||
public bool ShowHeader
|
||||
{
|
||||
get => _showHeader;
|
||||
set => MarkAsDirty(() => _showHeader = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the header style.
|
||||
/// </summary>
|
||||
public Style? HeaderStyle
|
||||
{
|
||||
get => _headerStyle;
|
||||
set => MarkAsDirty(() => _headerStyle = value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list containing all calendar events.
|
||||
/// </summary>
|
||||
@ -137,6 +157,7 @@ namespace Spectre.Console
|
||||
_dirty = true;
|
||||
_culture = CultureInfo.InvariantCulture;
|
||||
_highlightStyle = new Style(foreground: Color.Blue);
|
||||
_showHeader = true;
|
||||
_calendarEvents = new ListWithCallback<CalendarEvent>(() => _dirty = true);
|
||||
}
|
||||
|
||||
@ -176,6 +197,12 @@ namespace Spectre.Console
|
||||
BorderStyle = _borderStyle,
|
||||
};
|
||||
|
||||
if (ShowHeader)
|
||||
{
|
||||
var heading = new DateTime(Year, Month, Day).ToString("Y", culture).SafeMarkup();
|
||||
table.Heading = new Title(heading, HeaderStyle);
|
||||
}
|
||||
|
||||
// Add columns
|
||||
foreach (var order in GetWeekdays())
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace Spectre.Console
|
||||
/// <summary>
|
||||
/// Gets or sets the header.
|
||||
/// </summary>
|
||||
public PanelHeader? Header { get; set; }
|
||||
public Title? Header { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Panel"/> class.
|
||||
|
@ -16,6 +16,9 @@ namespace Spectre.Console
|
||||
private readonly List<TableColumn> _columns;
|
||||
private readonly List<List<IRenderable>> _rows;
|
||||
|
||||
private static Style _defaultHeadingStyle = new Style(Color.Silver);
|
||||
private static Style _defaultFootnoteStyle = new Style(Color.Grey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of columns in the table.
|
||||
/// </summary>
|
||||
@ -52,6 +55,16 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public int? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the table title.
|
||||
/// </summary>
|
||||
public Title? Heading { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the table footnote.
|
||||
/// </summary>
|
||||
public Title? Footnote { get; set; }
|
||||
|
||||
// Whether this is a grid or not.
|
||||
internal bool IsGrid { get; set; }
|
||||
|
||||
@ -186,8 +199,10 @@ namespace Spectre.Console
|
||||
// Add rows.
|
||||
rows.AddRange(_rows);
|
||||
|
||||
// Iterate all rows
|
||||
var result = new List<Segment>();
|
||||
result.AddRange(RenderAnnotation(context, Heading, tableWidth, _defaultHeadingStyle));
|
||||
|
||||
// Iterate all rows
|
||||
foreach (var (index, firstRow, lastRow, row) in rows.Enumerate())
|
||||
{
|
||||
var cellHeight = 1;
|
||||
@ -303,6 +318,8 @@ namespace Spectre.Console
|
||||
}
|
||||
}
|
||||
|
||||
result.AddRange(RenderAnnotation(context, Footnote, tableWidth, _defaultFootnoteStyle));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -375,6 +392,27 @@ namespace Spectre.Console
|
||||
return widths;
|
||||
}
|
||||
|
||||
private static IEnumerable<Segment> RenderAnnotation(
|
||||
RenderContext context, Title? header,
|
||||
int maxWidth, Style defaultStyle)
|
||||
{
|
||||
if (header == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var paragraph = new Markup(header.Text.Capitalize(), header.Style ?? defaultStyle)
|
||||
.SetAlignment(header.Alignment ?? Justify.Center)
|
||||
.SetOverflow(Overflow.Ellipsis);
|
||||
|
||||
foreach (var segment in ((IRenderable)paragraph).Render(context, maxWidth))
|
||||
{
|
||||
yield return segment;
|
||||
}
|
||||
|
||||
yield return Segment.LineBreak;
|
||||
}
|
||||
|
||||
private (int Min, int Max) MeasureColumn(TableColumn column, RenderContext options, int maxWidth)
|
||||
{
|
||||
var padding = column.Padding.GetWidth();
|
||||
|
@ -3,32 +3,32 @@ using System;
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a header.
|
||||
/// Represents a title.
|
||||
/// </summary>
|
||||
public sealed class PanelHeader : IAlignable
|
||||
public sealed class Title : IAlignable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the header text.
|
||||
/// Gets the title text.
|
||||
/// </summary>
|
||||
public string Text { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the header style.
|
||||
/// Gets or sets the title style.
|
||||
/// </summary>
|
||||
public Style? Style { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the header alignment.
|
||||
/// Gets or sets the title alignment.
|
||||
/// </summary>
|
||||
public Justify? Alignment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PanelHeader"/> class.
|
||||
/// Initializes a new instance of the <see cref="Title"/> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The header text.</param>
|
||||
/// <param name="style">The header style.</param>
|
||||
/// <param name="alignment">The header alignment.</param>
|
||||
public PanelHeader(string text, Style? style = null, Justify? alignment = null)
|
||||
/// <param name="text">The title text.</param>
|
||||
/// <param name="style">The title style.</param>
|
||||
/// <param name="alignment">The title alignment.</param>
|
||||
public Title(string text, Style? style = null, Justify? alignment = null)
|
||||
{
|
||||
Text = text ?? throw new ArgumentNullException(nameof(text));
|
||||
Style = style;
|
||||
@ -36,22 +36,22 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the header style.
|
||||
/// Sets the title style.
|
||||
/// </summary>
|
||||
/// <param name="style">The header style.</param>
|
||||
/// <param name="style">The title style.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public PanelHeader SetStyle(Style? style)
|
||||
public Title SetStyle(Style? style)
|
||||
{
|
||||
Style = style ?? Style.Plain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the header alignment.
|
||||
/// Sets the title alignment.
|
||||
/// </summary>
|
||||
/// <param name="alignment">The header alignment.</param>
|
||||
/// <param name="alignment">The title alignment.</param>
|
||||
/// <returns>The same instance so that multiple calls can be chained.</returns>
|
||||
public PanelHeader SetAlignment(Justify alignment)
|
||||
public Title SetAlignment(Justify alignment)
|
||||
{
|
||||
Alignment = alignment;
|
||||
return this;
|
Reference in New Issue
Block a user