CM glyphs

This commit is contained in:
Tig
2024-06-26 10:23:26 -07:00
parent 7fef0d8986
commit 2d7057d35e
5 changed files with 76 additions and 56 deletions

View File

@@ -437,4 +437,24 @@ public class GlyphDefinitions
public Rune CrossHv { get; set; } = (Rune)'╋';
#endregion
#region ----------------- ShadowStyle -----------------
/// <summary>Shadow - Vertical Start - Left Half Block - ▌ U+0258c</summary>
public Rune ShadowVerticalStart { get; set; } = (Rune)'▌'; // Half: '\u2596' ▖;
/// <summary>Shadow - Vertical - Left Half Block - ▌ U+0258c</summary>
public Rune ShadowVertical { get; set; } = (Rune)'▌';
/// <summary>Shadow - Horizontal Start - Upper Half Block - ▀ U+02580</summary>
public Rune ShadowHorizontalStart { get; set; } = (Rune)'▀'; // Half: ▝ U+0259d;
/// <summary>Shadow - Horizontal - Upper Half Block - ▀ U+02580</summary>
public Rune ShadowHorizontal { get; set; } = (Rune)'▀';
/// <summary>Shadow - Horizontal End - Quadrant Upper Left - ▘ U+02598</summary>
public Rune ShadowHorizontalEnd { get; set; } = (Rune)'▘';
#endregion
}

View File

@@ -1,18 +1,17 @@
#nullable enable
namespace Terminal.Gui;
namespace Terminal.Gui;
/// <summary>
/// Defines the style of shadow to be drawn on the right and bottom sides of the <see cref="View"/>.
/// Defines the style of shadow to be drawn on the right and bottom sides of the <see cref="View"/>.
/// </summary>
public enum ShadowStyle
{
/// <summary>
/// No shadow.
/// No shadow.
/// </summary>
None,
/// <summary>
/// A shadow that is drawn using block elements. Ideal for smaller views such as buttons.
/// A shadow that is drawn using block elements. Ideal for smaller views such as buttons.
/// </summary>
Opaque,

View File

@@ -6,19 +6,15 @@ namespace Terminal.Gui;
/// </summary>
internal class ShadowView : View
{
// TODO: Add these to CM.Glyphs
private readonly char VERTICAL_START_GLYPH = '\u258C'; // Half: '\u2596';
private readonly char VERTICAL_GLYPH = '\u258C';
private readonly char HORIZONTAL_START_GLYPH = '\u2580'; // Half: '\u259d';
private readonly char HORIZONTAL_GLYPH = '\u2580';
private readonly char HORIZONTAL_END_GLYPH = '\u2598';
private ShadowStyle _shadowStyle;
/// <inheritdoc/>
public override Attribute GetNormalColor ()
{
if (SuperView is Adornment adornment)
{
Attribute attr = Attribute.Default;
var attr = Attribute.Default;
if (adornment.Parent.SuperView is { })
{
attr = adornment.Parent.SuperView.GetNormalColor ();
@@ -27,8 +23,11 @@ internal class ShadowView : View
{
attr = Application.Top.GetNormalColor ();
}
return new (new Attribute (ShadowStyle == ShadowStyle.Opaque ? Color.Black : attr.Foreground.GetDarkerColor (),
ShadowStyle == ShadowStyle.Opaque ? attr.Background : attr.Background.GetDarkerColor()));
return new (
new Attribute (
ShadowStyle == ShadowStyle.Opaque ? Color.Black : attr.Foreground.GetDarkerColor (),
ShadowStyle == ShadowStyle.Opaque ? attr.Background : attr.Background.GetDarkerColor ()));
}
return base.GetNormalColor ();
@@ -77,7 +76,6 @@ internal class ShadowView : View
/// </summary>
public Orientation Orientation { get; set; }
private ShadowStyle _shadowStyle;
public override ShadowStyle ShadowStyle
{
get => _shadowStyle;
@@ -91,22 +89,23 @@ internal class ShadowView : View
private void DrawHorizontalShadowOpaque (Rectangle rectangle)
{
// Draw the start glyph
AddRune (0, 0, (Rune)HORIZONTAL_START_GLYPH);
AddRune (0, 0, Glyphs.ShadowHorizontalStart);
// Fill the rest of the rectangle with the glyph
// Fill the rest of the rectangle with the glyph - note we skip the last since vertical will draw it
for (var i = 1; i < rectangle.Width - 1; i++)
{
AddRune (i, 0, (Rune)HORIZONTAL_GLYPH);
AddRune (i, 0, Glyphs.ShadowHorizontal);
}
// Last is special
AddRune (rectangle.Width - 1, 0, (Rune)HORIZONTAL_END_GLYPH);
AddRune (rectangle.Width - 1, 0, Glyphs.ShadowHorizontalEnd);
}
private void DrawHorizontalShadowTransparent (Rectangle viewport)
{
Rectangle screen = ViewportToScreen (viewport);
// Fill the rest of the rectangle - note we skip the last since vertical will draw it
for (int i = screen.X; i < screen.X + screen.Width - 1; i++)
{
Driver.Move (i, screen.Y);
@@ -117,12 +116,12 @@ internal class ShadowView : View
private void DrawVerticalShadowOpaque (Rectangle viewport)
{
// Draw the start glyph
AddRune (0, 0, (Rune)VERTICAL_START_GLYPH);
AddRune (0, 0, Glyphs.ShadowVerticalStart);
// Fill the rest of the rectangle with the glyph
for (var i = 1; i < viewport.Height; i++)
{
AddRune (0, i, (Rune)VERTICAL_GLYPH);
AddRune (0, i, Glyphs.ShadowVertical);
}
}
@@ -130,7 +129,7 @@ internal class ShadowView : View
{
Rectangle screen = ViewportToScreen (viewport);
// Fill the rest of the rectangle with the glyph
// Fill the rest of the rectangle
for (int i = screen.Y; i < screen.Y + viewport.Height; i++)
{
Driver.Move (screen.X, i);

View File

@@ -7,9 +7,9 @@ using Terminal.Gui;
namespace UICatalog.Scenarios;
[ScenarioMetadata ("3D Effects Demo", "Demonstrates 3D UI Effects.")]
[ScenarioMetadata ("ShadowStyles Demo", "Demonstrates ShadowStyles Effects.")]
[ScenarioCategory ("Layout")]
public class ThreeD : Scenario
public class ShadowStyles : Scenario
{
public override void Main ()
{

View File

@@ -7,11 +7,10 @@ public class ShadowStyleTests (ITestOutputHelper _output)
[Fact]
public void Default_None ()
{
View view = new View ();
var view = new View ();
Assert.Equal (ShadowStyle.None, view.ShadowStyle);
Assert.Equal (ShadowStyle.None, view.Margin.ShadowStyle);
view.Dispose ();
}
[Theory]
@@ -20,13 +19,12 @@ public class ShadowStyleTests (ITestOutputHelper _output)
[InlineData (ShadowStyle.Transparent)]
public void Set_View_Sets_Margin (ShadowStyle style)
{
View view = new View ();
var view = new View ();
view.ShadowStyle = style;
Assert.Equal (style, view.ShadowStyle);
Assert.Equal (style, view.Margin.ShadowStyle);
view.Dispose ();
}
[Theory]
@@ -35,41 +33,46 @@ public class ShadowStyleTests (ITestOutputHelper _output)
[InlineData (ShadowStyle.Transparent, 4)]
public void Style_Changes_Magin_Thickness (ShadowStyle style, int expected)
{
View view = new View ();
var view = new View ();
view.Margin.Thickness = new (3);
view.ShadowStyle = style;
Assert.Equal (new Thickness (3, 3, expected, expected), view.Margin.Thickness);
Assert.Equal (new (3, 3, expected, expected), view.Margin.Thickness);
view.ShadowStyle = ShadowStyle.None;
Assert.Equal (new Thickness (3), view.Margin.Thickness);
Assert.Equal (new (3), view.Margin.Thickness);
view.Dispose ();
}
// Visual tests
[Theory]
[InlineData (ShadowStyle.None, """
01#$
AB#$
!@#$
!@#$
""")]
[InlineData (ShadowStyle.Opaque, """
01#$
AB▌$
!▀▘$
!@#$
""")]
[InlineData (ShadowStyle.Transparent, """
01#$
AB#$
!@#$
!@#$
""")]
[InlineData (
ShadowStyle.None,
"""
01#$
AB#$
!@#$
!@#$
""")]
[InlineData (
ShadowStyle.Opaque,
"""
01#$
AB▌$
!▀▘$
!@#$
""")]
[InlineData (
ShadowStyle.Transparent,
"""
01#$
AB#$
!@#$
!@#$
""")]
[SetupFakeDriver]
public void Visual_Test (ShadowStyle style, string expected)
{
View superView = new View ()
var superView = new View
{
Width = 4,
Height = 4,
@@ -77,19 +80,18 @@ public class ShadowStyleTests (ITestOutputHelper _output)
};
superView.TextFormatter.WordWrap = true;
View view = new View ()
var view = new View
{
Text = "01\nAB",
Width = Dim.Auto (),
Height = Dim.Auto (),
Height = Dim.Auto ()
};
view.ShadowStyle = style;
superView.Add (view);
superView.BeginInit();
superView.EndInit();
superView.BeginInit ();
superView.EndInit ();
superView.Draw ();
// view.Draw ();
TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
view.Dispose ();
}