diff --git a/Terminal.Gui/Windows/Dialog.cs b/Terminal.Gui/Windows/Dialog.cs
index b51e5a8ae..5696adbff 100644
--- a/Terminal.Gui/Windows/Dialog.cs
+++ b/Terminal.Gui/Windows/Dialog.cs
@@ -109,24 +109,115 @@ namespace Terminal.Gui {
LayoutSubviews ();
}
+ // Get the width of all buttons, not including any spacing
internal int GetButtonsWidth ()
{
if (buttons.Count == 0) {
return 0;
}
- return buttons.Select (b => b.Bounds.Width).Sum () + buttons.Count - 1;
+ return buttons.Select (b => b.Bounds.Width).Sum ();
}
+ ///
+ /// Determines the horizontal alignment of the Dialog buttons.
+ ///
+ public enum ButtonAlignments {
+ ///
+ /// Center-aligns the buttons (the default).
+ ///
+ Center = 0,
+
+ ///
+ /// Justifies the buttons
+ ///
+ Justify,
+
+ ///
+ /// Left-aligns the buttons
+ ///
+ Left,
+
+ ///
+ /// Right-aligns the buttons
+ ///
+ Right
+ }
+
+ private ButtonAlignments buttonAlignment = Dialog.ButtonAlignments.Center;
+
+ ///
+ /// Determines how the s are aligned along the
+ /// bottom of the dialog.
+ ///
+ public ButtonAlignments ButtonAlignment { get => buttonAlignment; set => buttonAlignment = value; }
void LayoutStartedHandler ()
{
- int buttonsWidth = GetButtonsWidth ();
+ if (buttons.Count == 0) return;
- int shiftLeft = Math.Max ((Bounds.Width - buttonsWidth) / 2 - 2, 0);
- for (int i = buttons.Count - 1; i >= 0; i--) {
- Button button = buttons [i];
- shiftLeft += button.Frame.Width + 1;
- button.X = Pos.AnchorEnd (shiftLeft);
- button.Y = Pos.AnchorEnd (1);
+ int shiftLeft = 0;
+
+ int buttonsWidth = GetButtonsWidth ();
+ switch (ButtonAlignment) {
+ case ButtonAlignments.Center:
+ // Center Buttons
+ shiftLeft = Math.Max ((Bounds.Width - buttonsWidth - buttons.Count - 2) / 2 + 1, 0);
+ for (int i = buttons.Count - 1; i >= 0; i--) {
+ Button button = buttons [i];
+ shiftLeft += button.Frame.Width + (i == buttons.Count - 1 ? 0 : 1);
+ button.X = Pos.AnchorEnd (shiftLeft);
+ button.Y = Pos.AnchorEnd (1);
+ }
+ break;
+
+ case ButtonAlignments.Justify:
+ // Justify Buttons
+ // leftmost and rightmost buttons are hard against edges. The rest are evenly spaced.
+
+ var spacing = (int)Math.Ceiling ((double)(Bounds.Width - buttonsWidth - 2) / (buttons.Count - 1));
+ for (int i = buttons.Count - 1; i >= 0; i--) {
+ Button button = buttons [i];
+ if (i == buttons.Count - 1) {
+ shiftLeft += button.Frame.Width;
+ button.X = Pos.AnchorEnd (shiftLeft);
+ } else {
+ if (i == 0) {
+ // first (leftmost) button - always hard flush left
+ var left = Bounds.Width - 2;
+ button.X = Pos.AnchorEnd (left);
+ } else {
+ shiftLeft += button.Frame.Width + (spacing);
+ button.X = Pos.AnchorEnd (shiftLeft);
+ }
+ }
+ button.Y = Pos.AnchorEnd (1);
+ }
+ break;
+
+ case ButtonAlignments.Left:
+ // Left Align Buttons
+ var prevButton = buttons [0];
+ prevButton.X = 0;
+ prevButton.Y = Pos.AnchorEnd (1);
+ for (int i = 1; i < buttons.Count; i++) {
+ Button button = buttons [i];
+ button.X = Pos.Right (prevButton) + 1;
+ button.Y = Pos.AnchorEnd (1);
+ prevButton = button;
+ }
+ break;
+
+ case ButtonAlignments.Right:
+ // Right align buttons
+ shiftLeft = buttons [buttons.Count - 1].Frame.Width;
+ buttons [buttons.Count - 1].X = Pos.AnchorEnd (shiftLeft);
+ buttons [buttons.Count - 1].Y = Pos.AnchorEnd (1);
+ for (int i = buttons.Count - 2; i >= 0; i--) {
+ Button button = buttons [i];
+ shiftLeft += button.Frame.Width + 1;
+ button.X = Pos.AnchorEnd (shiftLeft);
+ button.Y = Pos.AnchorEnd (1);
+ }
+ break;
}
}
@@ -140,5 +231,6 @@ namespace Terminal.Gui {
}
return base.ProcessKey (kb);
}
+
}
}
diff --git a/UICatalog/Scenarios/Dialogs.cs b/UICatalog/Scenarios/Dialogs.cs
index 3da4ae548..6d43fd7ec 100644
--- a/UICatalog/Scenarios/Dialogs.cs
+++ b/UICatalog/Scenarios/Dialogs.cs
@@ -9,13 +9,13 @@ namespace UICatalog.Scenarios {
[ScenarioMetadata (Name: "Dialogs", Description: "Demonstrates how to the Dialog class")]
[ScenarioCategory ("Dialogs")]
public class Dialogs : Scenario {
+ static int CODE_POINT = '你'; // We know this is a wide char
public override void Setup ()
{
var frame = new FrameView ("Dialog Options") {
X = Pos.Center (),
- Y = 1,
- Width = Dim.Percent (75),
- Height = 10
+ Y = 0,
+ Width = Dim.Percent (75)
};
Win.Add (frame);
@@ -92,10 +92,31 @@ namespace UICatalog.Scenarios {
};
frame.Add (numButtonsEdit);
+ var glyphsNotWords = new CheckBox ($"Add {Char.ConvertFromUtf32(CODE_POINT)} to button text to stress wide char support", false) {
+ X = Pos.Left (numButtonsEdit),
+ Y = Pos.Bottom (label),
+ TextAlignment = Terminal.Gui.TextAlignment.Right,
+ };
+ frame.Add (glyphsNotWords);
+
+
+ label = new Label ("Button Style:") {
+ X = 0,
+ Y = Pos.Bottom (glyphsNotWords),
+ AutoSize = true,
+ TextAlignment = Terminal.Gui.TextAlignment.Right,
+ };
+ frame.Add (label);
+ var styleRadioGroup = new RadioGroup (new ustring [] { "Center", "Justify", "Left", "Right" }) {
+ X = Pos.Right (label) + 1,
+ Y = Pos.Top (label),
+ };
+ frame.Add (styleRadioGroup);
+
void Top_Loaded ()
{
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit)
- + Dim.Height (numButtonsEdit) + 2;
+ + Dim.Height (numButtonsEdit) + Dim.Height (styleRadioGroup) + Dim.Height(glyphsNotWords) + 2;
Top.Loaded -= Top_Loaded;
}
Top.Loaded += Top_Loaded;
@@ -112,10 +133,14 @@ namespace UICatalog.Scenarios {
Y = Pos.Bottom (frame) + 5,
Width = 25,
Height = 1,
+
ColorScheme = Colors.Error,
};
+ // glyphsNotWords
+ // false:var btnText = new [] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" };
+ // true: var btnText = new [] { "0", "\u2780", "➁", "\u2783", "\u2784", "\u2785", "\u2786", "\u2787", "\u2788", "\u2789" };
+ // \u2781 is ➁ dingbats \ufb70 is
- //var btnText = new [] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" };
var showDialogButton = new Button ("Show Dialog") {
X = Pos.Center (),
Y = Pos.Bottom (frame) + 2,
@@ -123,18 +148,26 @@ namespace UICatalog.Scenarios {
};
showDialogButton.Clicked += () => {
try {
- int width = int.Parse (widthEdit.Text.ToString ());
- int height = int.Parse (heightEdit.Text.ToString ());
- int numButtons = int.Parse (numButtonsEdit.Text.ToString ());
+ int width = 0;
+ int.TryParse (widthEdit.Text.ToString (), out width);
+ int height = 0;
+ int.TryParse (heightEdit.Text.ToString (), out height);
+ int numButtons = 3;
+ int.TryParse (numButtonsEdit.Text.ToString (), out numButtons);
var buttons = new List