mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-27 00:07:58 +01:00
WIP: Fixing MessagBox to use Dim.Auto
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Terminal.Gui;
|
||||
|
||||
@@ -176,10 +177,10 @@ public class Dim
|
||||
/// <param name="maximumContentDim">The maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED.</param>
|
||||
public static Dim Auto (DimAutoStyle style = DimAutoStyle.Auto, Dim minimumContentDim = null, Dim maximumContentDim = null)
|
||||
{
|
||||
if (maximumContentDim != null)
|
||||
{
|
||||
throw new NotImplementedException (@"maximumContentDim is not implemented");
|
||||
}
|
||||
//if (maximumContentDim != null)
|
||||
//{
|
||||
// throw new NotImplementedException (@"maximumContentDim is not implemented");
|
||||
//}
|
||||
|
||||
return new DimAuto (style, minimumContentDim, maximumContentDim);
|
||||
}
|
||||
@@ -459,29 +460,71 @@ public class DimAuto (DimAutoStyle style, Dim minimumContentDim, Dim maximumCont
|
||||
// TODO: If _min > 0 we can SetRelativeLayout for the subviews?
|
||||
subviewsSize = 0;
|
||||
|
||||
if (us.Subviews.Count > 0)
|
||||
List<View> subviews;
|
||||
|
||||
if (dimension == Dimension.Width)
|
||||
{
|
||||
for (var i = 0; i < us.Subviews.Count; i++)
|
||||
subviews = us.Subviews.Where (v => v.X is not PosAnchorEnd && v.Width is not DimFill).ToList ();
|
||||
}
|
||||
else
|
||||
{
|
||||
subviews = us.Subviews.Where (v => v.Y is not PosAnchorEnd && v.Height is not DimFill).ToList ();
|
||||
}
|
||||
|
||||
for (var i = 0; i < subviews.Count; i++)
|
||||
{
|
||||
View v = subviews [i];
|
||||
|
||||
int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
||||
|
||||
if (size > subviewsSize)
|
||||
{
|
||||
View v = us.Subviews [i];
|
||||
bool isNotPosAnchorEnd = dimension == Dimension.Width ? v.X is not PosAnchorEnd : v.Y is not PosAnchorEnd;
|
||||
|
||||
//if (!isNotPosAnchorEnd)
|
||||
//{
|
||||
// v.SetRelativeLayout(dimension == Dimension.Width ? (new Size (autoMin, 0)) : new Size (0, autoMin));
|
||||
//}
|
||||
|
||||
if (isNotPosAnchorEnd)
|
||||
{
|
||||
int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
||||
|
||||
if (size > subviewsSize)
|
||||
{
|
||||
subviewsSize = size;
|
||||
}
|
||||
}
|
||||
subviewsSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (dimension == Dimension.Width)
|
||||
{
|
||||
subviews = us.Subviews.Where (v => v.X is PosAnchorEnd).ToList ();
|
||||
}
|
||||
else
|
||||
{
|
||||
subviews = us.Subviews.Where (v => v.Y is PosAnchorEnd).ToList ();
|
||||
}
|
||||
|
||||
int maxAnchorEnd = 0;
|
||||
for (var i = 0; i < subviews.Count; i++)
|
||||
{
|
||||
View v = subviews [i];
|
||||
maxAnchorEnd = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
|
||||
}
|
||||
|
||||
subviewsSize += maxAnchorEnd;
|
||||
|
||||
|
||||
if (dimension == Dimension.Width)
|
||||
{
|
||||
subviews = us.Subviews.Where (v => v.Width is DimFill).ToList ();
|
||||
}
|
||||
else
|
||||
{
|
||||
subviews = us.Subviews.Where (v => v.Height is DimFill).ToList ();
|
||||
}
|
||||
|
||||
for (var i = 0; i < subviews.Count; i++)
|
||||
{
|
||||
View v = subviews [i];
|
||||
|
||||
if (dimension == Dimension.Width)
|
||||
{
|
||||
v.SetRelativeLayout (new Size (subviewsSize, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
v.SetRelativeLayout (new Size (0, autoMin - subviewsSize));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,11 +786,11 @@ public class DimView : Dim
|
||||
}
|
||||
|
||||
string dimString = Dimension switch
|
||||
{
|
||||
Dimension.Height => "Height",
|
||||
Dimension.Width => "Width",
|
||||
_ => "unknown"
|
||||
};
|
||||
{
|
||||
Dimension.Height => "Height",
|
||||
Dimension.Width => "Width",
|
||||
_ => "unknown"
|
||||
};
|
||||
|
||||
return $"View({dimString},{Target})";
|
||||
}
|
||||
@@ -755,11 +798,11 @@ public class DimView : Dim
|
||||
internal override int Anchor (int size)
|
||||
{
|
||||
return Dimension switch
|
||||
{
|
||||
Dimension.Height => Target.Frame.Height,
|
||||
Dimension.Width => Target.Frame.Width,
|
||||
_ => 0
|
||||
};
|
||||
{
|
||||
Dimension.Height => Target.Frame.Height,
|
||||
Dimension.Width => Target.Frame.Width,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
|
||||
internal override bool ReferencesOtherViews () { return true; }
|
||||
|
||||
@@ -314,14 +314,14 @@ public partial class View
|
||||
{
|
||||
get
|
||||
{
|
||||
#if DEBUG
|
||||
if ((_width.ReferencesOtherViews () || _height.ReferencesOtherViews ()) && !IsInitialized)
|
||||
{
|
||||
Debug.WriteLine (
|
||||
$"WARNING: The dimensions of {this} are dependent on other views and Viewport is being accessed before the View has been initialized. This is likely a bug."
|
||||
);
|
||||
}
|
||||
#endif // DEBUG
|
||||
//#if DEBUG
|
||||
// if ((_width.ReferencesOtherViews () || _height.ReferencesOtherViews ()) && !IsInitialized)
|
||||
// {
|
||||
// Debug.WriteLine (
|
||||
// $"WARNING: The dimensions of {this} are dependent on other views and Viewport is being accessed before the View has been initialized. This is likely a bug."
|
||||
// );
|
||||
// }
|
||||
//#endif // DEBUG
|
||||
|
||||
if (Margin is null || Border is null || Padding is null)
|
||||
{
|
||||
|
||||
@@ -75,8 +75,14 @@ public class Dialog : Window
|
||||
return true;
|
||||
});
|
||||
KeyBindings.Add (Key.Esc, Command.QuitToplevel);
|
||||
|
||||
Initialized += Dialog_Initialized; ;
|
||||
}
|
||||
|
||||
private void Dialog_Initialized (object sender, EventArgs e)
|
||||
{
|
||||
LayoutButtons ();
|
||||
}
|
||||
|
||||
private bool _canceled;
|
||||
|
||||
@@ -158,18 +164,19 @@ public class Dialog : Window
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void LayoutSubviews ()
|
||||
{
|
||||
if (_inLayout)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//public override void LayoutSubviews ()
|
||||
//{
|
||||
// if (_inLayout)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
_inLayout = true;
|
||||
LayoutButtons ();
|
||||
base.LayoutSubviews ();
|
||||
_inLayout = false;
|
||||
}
|
||||
// _inLayout = true;
|
||||
// SetRelativeLayout(SuperView?.ContentSize ?? Driver.Screen.Size);
|
||||
// LayoutButtons ();
|
||||
// base.LayoutSubviews ();
|
||||
// _inLayout = false;
|
||||
//}
|
||||
|
||||
// Get the width of all buttons, not including any Margin.
|
||||
internal int GetButtonsWidth ()
|
||||
@@ -216,7 +223,7 @@ public class Dialog : Window
|
||||
button.X = Viewport.Width - shiftLeft;
|
||||
}
|
||||
|
||||
button.Y = Pos.AnchorEnd (1);
|
||||
button.Y = Pos.AnchorEnd ();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -251,7 +258,7 @@ public class Dialog : Window
|
||||
}
|
||||
}
|
||||
|
||||
button.Y = Pos.AnchorEnd (1);
|
||||
button.Y = Pos.AnchorEnd ();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -283,7 +290,7 @@ public class Dialog : Window
|
||||
Button button = _buttons [i];
|
||||
shiftLeft += button.Frame.Width + 1;
|
||||
button.X = Pos.AnchorEnd (shiftLeft);
|
||||
button.Y = Pos.AnchorEnd (1);
|
||||
button.Y = Pos.AnchorEnd ();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -344,8 +344,8 @@ public static class MessageBox
|
||||
Buttons = buttonList.ToArray (),
|
||||
Title = title,
|
||||
BorderStyle = DefaultBorderStyle,
|
||||
Width = Dim.Percent (60),
|
||||
Height = 5 // Border + one line of text + vspace + buttons
|
||||
Width = Dim.Auto (DimAutoStyle.Content),
|
||||
Height = Dim.Auto (DimAutoStyle.Content),
|
||||
};
|
||||
|
||||
if (width != 0)
|
||||
@@ -372,17 +372,26 @@ public static class MessageBox
|
||||
Text = message,
|
||||
TextAlignment = TextAlignment.Centered,
|
||||
X = Pos.Center (),
|
||||
Y = 0
|
||||
Y = 0,
|
||||
// ColorScheme = Colors.ColorSchemes ["Error"]
|
||||
};
|
||||
|
||||
messageLabel.TextFormatter.WordWrap = wrapMessage;
|
||||
messageLabel.TextFormatter.MultiLine = !wrapMessage;
|
||||
|
||||
if (wrapMessage)
|
||||
{
|
||||
messageLabel.Width = Dim.Fill ();
|
||||
messageLabel.Height = Dim.Fill (1);
|
||||
int GetWrapSize ()
|
||||
{
|
||||
// A bit of a hack to get the height of the wrapped text.
|
||||
messageLabel.TextFormatter.Size = new (d.ContentSize.Width, 1000);
|
||||
return messageLabel.TextFormatter.FormatAndGetSize ().Height;
|
||||
}
|
||||
d.Height = Dim.Auto (DimAutoStyle.Content, minimumContentDim: Dim.Func (GetWrapSize) + 1);
|
||||
}
|
||||
|
||||
messageLabel.TextFormatter.WordWrap = wrapMessage;
|
||||
messageLabel.TextFormatter.MultiLine = !wrapMessage;
|
||||
d.Add (messageLabel);
|
||||
|
||||
// Setup actions
|
||||
@@ -405,69 +414,11 @@ public static class MessageBox
|
||||
}
|
||||
}
|
||||
|
||||
d.Loaded += Dialog_Loaded;
|
||||
|
||||
// Run the modal; do not shutdown the mainloop driver when done
|
||||
Application.Run (d);
|
||||
d.Dispose ();
|
||||
|
||||
return Clicked;
|
||||
|
||||
void Dialog_Loaded (object s, EventArgs e)
|
||||
{
|
||||
if (width != 0 || height != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: replace with Dim.Fit when implemented
|
||||
Rectangle maxBounds = d.SuperView?.Viewport ?? Application.Top.Viewport;
|
||||
|
||||
Thickness adornmentsThickness = d.GetAdornmentsThickness ();
|
||||
|
||||
if (wrapMessage)
|
||||
{
|
||||
messageLabel.TextFormatter.Size = new (
|
||||
maxBounds.Size.Width
|
||||
- adornmentsThickness.Horizontal,
|
||||
maxBounds.Size.Height
|
||||
- adornmentsThickness.Vertical);
|
||||
}
|
||||
|
||||
string msg = messageLabel.TextFormatter.Format ();
|
||||
Size messageSize = messageLabel.TextFormatter.FormatAndGetSize ();
|
||||
|
||||
// Ensure the width fits the text + buttons
|
||||
int newWidth = Math.Max (
|
||||
width,
|
||||
Math.Max (
|
||||
messageSize.Width + adornmentsThickness.Horizontal,
|
||||
d.GetButtonsWidth () + d.Buttons.Length + adornmentsThickness.Horizontal));
|
||||
|
||||
if (newWidth > d.Frame.Width)
|
||||
{
|
||||
d.Width = newWidth;
|
||||
}
|
||||
|
||||
// Ensure height fits the text + vspace + buttons
|
||||
if (messageSize.Height == 0)
|
||||
{
|
||||
d.Height = Math.Max (height, 3 + adornmentsThickness.Vertical);
|
||||
}
|
||||
else
|
||||
{
|
||||
string lastLine = messageLabel.TextFormatter.GetLines () [^1];
|
||||
|
||||
// INTENT: Instead of the check against \n or \r\n, how about just Environment.NewLine?
|
||||
d.Height = Math.Max (
|
||||
height,
|
||||
messageSize.Height
|
||||
+ (lastLine.EndsWith ("\r\n") || lastLine.EndsWith ('\n') ? 1 : 2)
|
||||
+ adornmentsThickness.Vertical);
|
||||
}
|
||||
|
||||
d.SetRelativeLayout (d.SuperView?.ContentSize ?? Application.Top.ContentSize);
|
||||
d.LayoutSubviews ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public class DimAutoDemo : Scenario
|
||||
{
|
||||
Text = "_Reset Button (AnchorEnd)",
|
||||
X = Pos.AnchorEnd (),
|
||||
Y = Pos.AnchorEnd ()
|
||||
Y = Pos.AnchorEnd (1)
|
||||
};
|
||||
|
||||
resetButton.Accept += (s, e) => { movingButton.Y = Pos.Bottom (hlabel); };
|
||||
|
||||
@@ -114,7 +114,7 @@ public class MessageBoxes : Scenario
|
||||
|
||||
var messageEdit = new TextView
|
||||
{
|
||||
Text = "Message",
|
||||
Text = "Message line 1.\nMessage line two. This is a really long line to force wordwrap. It needs to be long for it to work.",
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = Dim.Fill (),
|
||||
@@ -186,7 +186,7 @@ public class MessageBoxes : Scenario
|
||||
|
||||
var ckbWrapMessage = new CheckBox
|
||||
{
|
||||
X = Pos.Right (label) + 1, Y = Pos.Bottom (styleRadioGroup), Text = "_Wrap Message", Checked = true
|
||||
X = Pos.Right (label) + 1, Y = Pos.Bottom (styleRadioGroup), Text = "_Wrap Message", Checked = false
|
||||
};
|
||||
frame.Add (ckbWrapMessage);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user