mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Merge branch 'v2_2432-DimAuto' into tig_v2_2432-DimAuto
This commit is contained in:
@@ -939,11 +939,18 @@ public class Dim
|
||||
|
||||
if (_style is Dim.DimAutoStyle.Subviews or Dim.DimAutoStyle.Auto)
|
||||
{
|
||||
subviewsSize = us.Subviews.Count == 0
|
||||
? 0
|
||||
: us.Subviews
|
||||
.Where (v => dimension == Dimension.Width ? v.X is not Pos.PosAnchorEnd : v.Y is not Pos.PosAnchorEnd)
|
||||
.Max (v => dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height);
|
||||
if (us.IdealContentSize.HasValue)
|
||||
{
|
||||
subviewsSize = dimension == Dimension.Width ? us.IdealContentSize.Value.Width : us.IdealContentSize.Value.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
subviewsSize = us.Subviews.Count == 0
|
||||
? 0
|
||||
: us.Subviews
|
||||
.Where (v => dimension == Dimension.Width ? v.X is not Pos.PosAnchorEnd : v.Y is not Pos.PosAnchorEnd)
|
||||
.Max (v => dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height);
|
||||
}
|
||||
}
|
||||
|
||||
int max = int.Max (textSize, subviewsSize);
|
||||
|
||||
@@ -91,10 +91,12 @@ public partial class View
|
||||
private void SetFrame (Rectangle frame)
|
||||
{
|
||||
var oldViewport = Rectangle.Empty;
|
||||
var oldContentSize = Size.Empty;
|
||||
|
||||
if (IsInitialized)
|
||||
{
|
||||
oldViewport = Viewport;
|
||||
oldContentSize = ContentSize;
|
||||
}
|
||||
|
||||
// This is the only place where _frame should be set directly. Use Frame = or SetFrame instead.
|
||||
@@ -341,6 +343,18 @@ public partial class View
|
||||
|
||||
#region Layout Engine
|
||||
|
||||
|
||||
// @tig Notes on layout flow. Ignore for now.
|
||||
// BeginLayout
|
||||
// If !LayoutNeeded return
|
||||
// If !SizeNeeded return
|
||||
// Call OnLayoutStarted
|
||||
// Views and subviews can update things
|
||||
//
|
||||
|
||||
|
||||
// EndLayout
|
||||
|
||||
/// <summary>
|
||||
/// Controls how the View's <see cref="Frame"/> is computed during <see cref="LayoutSubviews"/>. If the style is
|
||||
/// set to <see cref="LayoutStyle.Absolute"/>, LayoutSubviews does not change the <see cref="Frame"/>. If the style is
|
||||
@@ -780,6 +794,7 @@ public partial class View
|
||||
|
||||
private void LayoutSubview (View v, Size contentSize)
|
||||
{
|
||||
// BUGBUG: Calling SetRelativeLayout before LayoutSubviews is problematic. Need to resolve.
|
||||
v.SetRelativeLayout (contentSize);
|
||||
v.LayoutSubviews ();
|
||||
v.LayoutNeeded = false;
|
||||
@@ -794,6 +809,9 @@ public partial class View
|
||||
/// </summary>
|
||||
internal virtual void OnLayoutComplete (LayoutEventArgs args) { LayoutComplete?.Invoke (this, args); }
|
||||
|
||||
// BUGBUG: We need an API/event that is called from SetRelativeLayout instead of/in addition to
|
||||
// BUGBUG: OnLayoutStarted which is called from LayoutSubviews.
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="LayoutStarted"/> event. Called from <see cref="LayoutSubviews"/> before any subviews
|
||||
/// have been laid out.
|
||||
|
||||
@@ -155,6 +155,8 @@ public partial class View
|
||||
}
|
||||
}
|
||||
|
||||
public Size? IdealContentSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when <see cref="ContentSize"/> changes. Invokes the <see cref="ContentSizeChanged"/> event.
|
||||
/// </summary>
|
||||
@@ -319,10 +321,8 @@ public partial class View
|
||||
|
||||
// Whenever DimAutoStyle.Text is set, ContentSize will match TextFormatter.Size.
|
||||
ContentSize = TextFormatter.Size;
|
||||
|
||||
}
|
||||
}
|
||||
//SetRelativeLayout (SuperView?.ContentSize ?? new Size (int.MaxValue, int.MaxValue));
|
||||
}
|
||||
|
||||
return new (
|
||||
@@ -357,7 +357,6 @@ public partial class View
|
||||
}
|
||||
|
||||
OnViewportChanged (new (IsInitialized ? Viewport : Rectangle.Empty, oldViewport));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -417,7 +416,10 @@ public partial class View
|
||||
/// Called when the <see cref="Viewport"/> changes. Invokes the <see cref="ViewportChanged"/> event.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnViewportChanged (DrawEventArgs e) { ViewportChanged?.Invoke (this, e); }
|
||||
protected virtual void OnViewportChanged (DrawEventArgs e)
|
||||
{
|
||||
ViewportChanged?.Invoke (this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Viewport"/>-relative location to a screen-relative location.
|
||||
|
||||
@@ -265,11 +265,19 @@ public class Slider<T> : View
|
||||
|
||||
Enter += (s, e) => { };
|
||||
|
||||
LayoutComplete += (s, e) =>
|
||||
// BUGBUG: This should not be needed - Need to ensure SetRelativeLayout gets called during EndInit
|
||||
Initialized += (s, e) =>
|
||||
{
|
||||
CalcSpacingConfig ();
|
||||
SetContentSizeBestFit ();
|
||||
};
|
||||
|
||||
LayoutStarted += (s, e) =>
|
||||
{
|
||||
CalcSpacingConfig ();
|
||||
SetBoundsBestFit ();
|
||||
SetContentSizeBestFit ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -374,13 +382,9 @@ public class Slider<T> : View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If <see langword="true"/> the slider will be sized to fit the available space (the Viewport of the the
|
||||
/// SuperView).
|
||||
/// If <see langword="true"/>, <see cref="View.Width"/> and <see cref="View.Height"/> will be automatically set
|
||||
/// such that the slider will be optimally sized to fit the options using the various slider settings.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For testing, if there is no SuperView, the slider will be sized based on what <see cref="InnerSpacing"/> is
|
||||
/// set to.
|
||||
/// </remarks>
|
||||
[ObsoleteAttribute ("Use Dim.Auto instead.", false)]
|
||||
public override bool AutoSize
|
||||
{
|
||||
@@ -389,10 +393,15 @@ public class Slider<T> : View
|
||||
{
|
||||
_config._autoSize = value;
|
||||
|
||||
if (IsInitialized)
|
||||
if (value)
|
||||
{
|
||||
CalcSpacingConfig ();
|
||||
SetBoundsBestFit ();
|
||||
Width = Dim.Auto (Dim.DimAutoStyle.Subviews);
|
||||
Height = Dim.Auto (Dim.DimAutoStyle.Subviews);
|
||||
}
|
||||
else
|
||||
{
|
||||
Width = ContentSize.Width;
|
||||
Height = ContentSize.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -408,7 +417,7 @@ public class Slider<T> : View
|
||||
if (IsInitialized)
|
||||
{
|
||||
CalcSpacingConfig ();
|
||||
SetBoundsBestFit ();
|
||||
SetContentSizeBestFit ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -456,7 +465,7 @@ public class Slider<T> : View
|
||||
if (IsInitialized)
|
||||
{
|
||||
CalcSpacingConfig ();
|
||||
SetBoundsBestFit ();
|
||||
SetContentSizeBestFit ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +483,7 @@ public class Slider<T> : View
|
||||
if (IsInitialized)
|
||||
{
|
||||
CalcSpacingConfig ();
|
||||
SetBoundsBestFit ();
|
||||
SetContentSizeBestFit ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -508,7 +517,7 @@ public class Slider<T> : View
|
||||
}
|
||||
|
||||
CalcSpacingConfig ();
|
||||
SetBoundsBestFit ();
|
||||
SetContentSizeBestFit ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,7 +546,7 @@ public class Slider<T> : View
|
||||
set
|
||||
{
|
||||
_config._showLegends = value;
|
||||
SetBoundsBestFit ();
|
||||
SetContentSizeBestFit ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,9 +776,9 @@ public class Slider<T> : View
|
||||
}
|
||||
|
||||
/// <summary>Adjust the dimensions of the Slider to the best value if <see cref="AutoSize"/> is true.</summary>
|
||||
public void SetBoundsBestFit ()
|
||||
public void SetContentSizeBestFit ()
|
||||
{
|
||||
if (!IsInitialized || AutoSize == false)
|
||||
if (!IsInitialized || !(Height is Dim.DimAuto && Width is Dim.DimAuto))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -778,15 +787,16 @@ public class Slider<T> : View
|
||||
|
||||
if (_config._sliderOrientation == Orientation.Horizontal)
|
||||
{
|
||||
// BUGBUG: For this View, ContentSize == Viewport.Size, so this works. But for correctness we should be setting ContentSize here
|
||||
Viewport = new (
|
||||
Viewport.Location,
|
||||
new (
|
||||
int.Min (
|
||||
SuperView.Viewport.Width - adornmentsThickness.Horizontal,
|
||||
SuperView.ContentSize.Width - adornmentsThickness.Horizontal,
|
||||
CalcBestLength ()
|
||||
),
|
||||
int.Min (
|
||||
SuperView.Viewport.Height - adornmentsThickness.Vertical,
|
||||
SuperView.ContentSize.Height - adornmentsThickness.Vertical,
|
||||
CalcThickness ()
|
||||
)
|
||||
)
|
||||
@@ -794,15 +804,14 @@ public class Slider<T> : View
|
||||
}
|
||||
else
|
||||
{
|
||||
Viewport = new (
|
||||
Viewport.Location,
|
||||
IdealContentSize = new (
|
||||
new (
|
||||
int.Min (
|
||||
SuperView.Viewport.Width - adornmentsThickness.Horizontal,
|
||||
SuperView.ContentSize.Width - adornmentsThickness.Horizontal,
|
||||
CalcThickness ()
|
||||
),
|
||||
int.Min (
|
||||
SuperView.Viewport.Height - adornmentsThickness.Vertical,
|
||||
SuperView.ContentSize.Height - adornmentsThickness.Vertical,
|
||||
CalcBestLength ()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Terminal.Gui;
|
||||
@@ -384,6 +385,20 @@ public class ContentScrolling : Scenario
|
||||
longLabel.TextFormatter.WordWrap = true;
|
||||
view.Add (longLabel);
|
||||
|
||||
List<object> options = new () { "Option 1", "Option 2", "Option 3" };
|
||||
Slider slider = new (options)
|
||||
{
|
||||
X = 0,
|
||||
Y = Pos.Bottom (textField) + 1,
|
||||
AutoSize = true,
|
||||
Orientation = Orientation.Vertical,
|
||||
Type = SliderType.Multiple,
|
||||
AllowEmpty = false,
|
||||
BorderStyle = LineStyle.Double,
|
||||
Title = "_Slider"
|
||||
};
|
||||
view.Add(slider);
|
||||
|
||||
editor.Initialized += (s, e) => { editor.ViewToEdit = view; };
|
||||
|
||||
app.Closed += (s, e) => View.Diagnostics = _diagnosticFlags;
|
||||
|
||||
@@ -486,5 +486,44 @@ public class SliderTests
|
||||
Assert.Throws<ArgumentNullException> (() => slider.Options = null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
private void AutoSize_Respects_SuperView_ContentSize ()
|
||||
{
|
||||
View view = new ()
|
||||
{
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (),
|
||||
};
|
||||
|
||||
List<object> options = new () { "01234", "01234" };
|
||||
Slider slider = new (options)
|
||||
{
|
||||
Orientation = Orientation.Vertical,
|
||||
Type = SliderType.Multiple,
|
||||
Width = Dim.Auto (Dim.DimAutoStyle.Subviews),
|
||||
Height = Dim.Auto (Dim.DimAutoStyle.Subviews),
|
||||
//IdealContentSize = new (6, 2)
|
||||
};
|
||||
view.Add (slider);
|
||||
view.BeginInit ();
|
||||
view.EndInit ();
|
||||
|
||||
// BUGBUG: This should not be needed. EndInit should have called LayoutSubviews
|
||||
// BUGBUG: and LayoutSubviews should have
|
||||
view.LayoutSubviews ();
|
||||
|
||||
Size expectedSize = slider.Frame.Size;
|
||||
|
||||
Assert.Equal (new (6, 2), expectedSize);
|
||||
|
||||
view.ContentSize = new (1, 1);
|
||||
|
||||
view.LayoutSubviews ();
|
||||
slider.SetRelativeLayout (view.Viewport.Size);
|
||||
|
||||
Assert.Equal(new (1, 1), slider.Frame.Size);
|
||||
|
||||
}
|
||||
|
||||
// Add more tests for different scenarios and edge cases.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user