mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Added all views tester for draw/layout.
Made Adornment support being a subview for testing purposes.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using System.ComponentModel;
|
||||
using Terminal.Gui;
|
||||
using static Terminal.Gui.SpinnerStyle;
|
||||
using Attribute = Terminal.Gui.Attribute;
|
||||
|
||||
/// <summary>
|
||||
@@ -15,7 +16,7 @@ using Attribute = Terminal.Gui.Attribute;
|
||||
/// mouse input. Each can be customized by manipulating their Subviews.
|
||||
/// </para>
|
||||
/// </remarsk>
|
||||
public class Adornment : View
|
||||
public class Adornment : View, IDesignable
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public Adornment ()
|
||||
@@ -63,6 +64,7 @@ public class Adornment : View
|
||||
{
|
||||
Parent?.SetAdornmentFrames ();
|
||||
SetLayoutNeeded ();
|
||||
SetNeedsDisplay ();
|
||||
//Parent?.SetLayoutNeeded ();
|
||||
|
||||
OnThicknessChanged ();
|
||||
@@ -88,9 +90,12 @@ public class Adornment : View
|
||||
/// Adornments cannot be used as sub-views (see <see cref="Parent"/>); setting this property will throw
|
||||
/// <see cref="InvalidOperationException"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// While there are no real use cases for an Adornment being a subview, it is not explicitly dis-allowed to support testing. E.g. in AllViewsTester.
|
||||
/// </remarks>
|
||||
public override View? SuperView
|
||||
{
|
||||
get => null!;
|
||||
get => base.SuperView!;
|
||||
set => throw new InvalidOperationException (@"Adornments can not be Subviews or have SuperViews. Use Parent instead.");
|
||||
}
|
||||
|
||||
@@ -115,7 +120,7 @@ public class Adornment : View
|
||||
/// </remarks>
|
||||
public override Rectangle Viewport
|
||||
{
|
||||
get => Frame with { Location = Point.Empty };
|
||||
get => base.Viewport;
|
||||
set => throw new InvalidOperationException (@"The Viewport of an Adornment cannot be modified.");
|
||||
}
|
||||
|
||||
@@ -124,6 +129,14 @@ public class Adornment : View
|
||||
{
|
||||
if (Parent is null)
|
||||
{
|
||||
// While there are no real use cases for an Adornment being a subview, we support it for
|
||||
// testing. E.g. in AllViewsTester.
|
||||
if (SuperView is { })
|
||||
{
|
||||
Point super = SuperView.ViewportToScreen (Frame.Location);
|
||||
|
||||
return new (super, Frame.Size);
|
||||
}
|
||||
return Frame;
|
||||
}
|
||||
|
||||
@@ -254,4 +267,15 @@ public class Adornment : View
|
||||
// }
|
||||
//}
|
||||
#endregion Mouse Support
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
bool IDesignable.EnableForDesign ()
|
||||
{
|
||||
Thickness = new (3);
|
||||
Frame = new (0, 0, 10, 10);
|
||||
Diagnostics = ViewDiagnosticFlags.Padding;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public class Border : Adornment
|
||||
// TODO: Make Border.LineStyle inherit from the SuperView hierarchy
|
||||
// TODO: Right now, Window and FrameView use CM to set BorderStyle, which negates
|
||||
// TODO: all this.
|
||||
return Parent!.SuperView?.BorderStyle ?? LineStyle.None;
|
||||
return Parent?.SuperView?.BorderStyle ?? LineStyle.None;
|
||||
}
|
||||
set => _lineStyle = value;
|
||||
}
|
||||
@@ -634,12 +634,15 @@ public class Border : Adornment
|
||||
int maxTitleWidth = Math.Max (
|
||||
0,
|
||||
Math.Min (
|
||||
Parent!.TitleTextFormatter.FormatAndGetSize ().Width,
|
||||
Parent?.TitleTextFormatter.FormatAndGetSize ().Width ?? 0,
|
||||
Math.Min (screenBounds.Width - 4, borderBounds.Width - 4)
|
||||
)
|
||||
);
|
||||
|
||||
Parent.TitleTextFormatter.ConstrainToSize = new (maxTitleWidth, 1);
|
||||
if (Parent is { })
|
||||
{
|
||||
Parent.TitleTextFormatter.ConstrainToSize = new (maxTitleWidth, 1);
|
||||
}
|
||||
|
||||
int sideLineLength = borderBounds.Height;
|
||||
bool canDrawBorder = borderBounds is { Width: > 0, Height: > 0 };
|
||||
@@ -678,7 +681,7 @@ public class Border : Adornment
|
||||
}
|
||||
}
|
||||
|
||||
if (canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title) && !string.IsNullOrEmpty (Parent?.Title))
|
||||
if (Parent is {} && canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title) && !string.IsNullOrEmpty (Parent?.Title))
|
||||
{
|
||||
Attribute focus = Parent.GetNormalColor ();
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ public class ColorPicker16 : View
|
||||
{
|
||||
base.OnDrawContent (viewport);
|
||||
|
||||
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ());
|
||||
Driver?.SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ());
|
||||
var colorIndex = 0;
|
||||
|
||||
for (var y = 0; y < Math.Max (2, viewport.Height / BoxHeight); y++)
|
||||
@@ -149,7 +149,7 @@ public class ColorPicker16 : View
|
||||
continue;
|
||||
}
|
||||
|
||||
Driver.SetAttribute (new ((ColorName16)foregroundColorIndex, (ColorName16)colorIndex));
|
||||
Driver?.SetAttribute (new ((ColorName16)foregroundColorIndex, (ColorName16)colorIndex));
|
||||
bool selected = x == Cursor.X && y == Cursor.Y;
|
||||
DrawColorBox (x, y, selected);
|
||||
colorIndex++;
|
||||
@@ -223,7 +223,7 @@ public class ColorPicker16 : View
|
||||
for (var zoomedX = 0; zoomedX < BoxWidth; zoomedX++)
|
||||
{
|
||||
Move (x * BoxWidth + zoomedX, y * BoxHeight + zoomedY);
|
||||
Driver.AddRune ((Rune)' ');
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public partial class ColorPicker : View
|
||||
{
|
||||
base.OnDrawContent (viewport);
|
||||
Attribute normal = GetNormalColor ();
|
||||
Driver.SetAttribute (new (SelectedColor, normal.Background));
|
||||
Driver?.SetAttribute (new (SelectedColor, normal.Background));
|
||||
int y = _bars.Count + (Style.ShowColorName ? 1 : 0);
|
||||
AddRune (13, y, (Rune)'■');
|
||||
}
|
||||
|
||||
@@ -997,11 +997,11 @@ public class TextField : View
|
||||
}
|
||||
}
|
||||
|
||||
Driver.SetAttribute (GetFocusColor ());
|
||||
Driver?.SetAttribute (GetFocusColor ());
|
||||
|
||||
for (int i = col; i < width; i++)
|
||||
{
|
||||
Driver.AddRune ((Rune)' ');
|
||||
Driver?.AddRune ((Rune)' ');
|
||||
}
|
||||
|
||||
PositionCursor ();
|
||||
|
||||
@@ -360,7 +360,6 @@ public class AllViewsTester : Scenario
|
||||
|
||||
// Instantiate view
|
||||
var view = (View)Activator.CreateInstance (type);
|
||||
|
||||
if (view is IDesignable designable)
|
||||
{
|
||||
designable.EnableForDesign (ref _demoText);
|
||||
@@ -384,6 +383,7 @@ public class AllViewsTester : Scenario
|
||||
view.Initialized += CurrentView_Initialized;
|
||||
view.LayoutComplete += CurrentView_LayoutComplete;
|
||||
|
||||
view.Id = "_curView";
|
||||
_curView = view;
|
||||
_hostPane.Add (_curView);
|
||||
}
|
||||
|
||||
47
UnitTests/View/Draw/AllViewsDrawTests.cs
Normal file
47
UnitTests/View/Draw/AllViewsDrawTests.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Terminal.Gui.LayoutTests;
|
||||
|
||||
public class AllViewsDrawTests (ITestOutputHelper _output) : TestsAllViews
|
||||
{
|
||||
[Theory]
|
||||
[MemberData (nameof (AllViewTypes))]
|
||||
public void AllViews_Does_Not_Layout (Type viewType)
|
||||
{
|
||||
var view = (View)CreateInstanceIfNotGeneric (viewType);
|
||||
|
||||
if (view == null)
|
||||
{
|
||||
_output.WriteLine ($"Ignoring {viewType} - It's a Generic");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (view is IDesignable designable)
|
||||
{
|
||||
designable.EnableForDesign ();
|
||||
}
|
||||
|
||||
var drawContentCount = 0;
|
||||
view.DrawContent += (s, e) => drawContentCount++;
|
||||
|
||||
var layoutStartedCount = 0;
|
||||
view.LayoutStarted += (s, e) => layoutStartedCount++;
|
||||
|
||||
var layoutCompleteCount = 0;
|
||||
view.LayoutComplete += (s, e) => layoutCompleteCount++;
|
||||
|
||||
view.SetLayoutNeeded ();
|
||||
view.Layout ();
|
||||
|
||||
Assert.Equal (0, drawContentCount);
|
||||
Assert.Equal (1, layoutStartedCount);
|
||||
Assert.Equal (1, layoutCompleteCount);
|
||||
|
||||
view.Draw ();
|
||||
|
||||
Assert.Equal (1, drawContentCount);
|
||||
Assert.Equal (1, layoutStartedCount);
|
||||
Assert.Equal (1, layoutCompleteCount);
|
||||
}
|
||||
}
|
||||
41
UnitTests/View/Layout/LayoutTests.cs
Normal file
41
UnitTests/View/Layout/LayoutTests.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Terminal.Gui.LayoutTests;
|
||||
|
||||
public class LayoutTests (ITestOutputHelper _output) : TestsAllViews
|
||||
{
|
||||
[Theory]
|
||||
[MemberData (nameof (AllViewTypes))]
|
||||
public void AllViews_Layout_Does_Not_Draw (Type viewType)
|
||||
{
|
||||
var view = (View)CreateInstanceIfNotGeneric (viewType);
|
||||
|
||||
if (view == null)
|
||||
{
|
||||
_output.WriteLine ($"Ignoring {viewType} - It's a Generic");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (view is IDesignable designable)
|
||||
{
|
||||
designable.EnableForDesign ();
|
||||
}
|
||||
|
||||
var drawContentCount = 0;
|
||||
view.DrawContent += (s, e) => drawContentCount++;
|
||||
|
||||
var layoutStartedCount = 0;
|
||||
view.LayoutStarted += (s, e) => layoutStartedCount++;
|
||||
|
||||
var layoutCompleteCount = 0;
|
||||
view.LayoutComplete += (s, e) => layoutCompleteCount++;
|
||||
|
||||
view.SetLayoutNeeded ();
|
||||
view.Layout ();
|
||||
|
||||
Assert.Equal (0, drawContentCount);
|
||||
Assert.Equal (1, layoutStartedCount);
|
||||
Assert.Equal (1, layoutCompleteCount);
|
||||
}
|
||||
}
|
||||
@@ -807,4 +807,6 @@ public class SetLayoutTests (ITestOutputHelper output)
|
||||
Assert.Equal (19, v2.Frame.Height);
|
||||
t.Dispose ();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user