Messagebox

This commit is contained in:
Miguel de Icaza
2018-01-14 22:50:04 -05:00
parent 863343cd3e
commit fb70b45e58
6 changed files with 103 additions and 16 deletions

View File

@@ -800,8 +800,8 @@ namespace Terminal {
public Window (Rect frame, string title = null) : base (frame)
{
this.Title = title;
frame.Inflate (-1, -1);
contentView = new ContentView (frame);
var cFrame = new Rect (1, 1, frame.Width - 2, frame.Height - 2);
contentView = new ContentView (cFrame);
base.Add (contentView);
}

View File

@@ -47,6 +47,7 @@
<Compile Include="Views\ScrollView.cs" />
<Compile Include="Views\Dialog.cs" />
<Compile Include="Views\RadioGroup.cs" />
<Compile Include="Views\MessageBox.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="mono-curses.dll">

View File

@@ -16,6 +16,13 @@ namespace Terminal {
public class Dialog : Window {
List<Button> buttons = new List<Button> ();
/// <summary>
/// Initializes a new instance of the <see cref="T:Terminal.Dialog"/> class with an optional set of buttons to display
/// </summary>
/// <param name="title">Title for the dialog.</param>
/// <param name="width">Width for the dialog.</param>
/// <param name="height">Height for the dialog.</param>
/// <param name="buttons">Optional buttons to lay out at the bottom of the dialog.</param>
public Dialog (string title, int width, int height, params Button [] buttons) : base (Application.MakeCenteredRect (new Size (width, height)), title)
{
foreach (var b in buttons) {
@@ -24,6 +31,20 @@ namespace Terminal {
}
}
/// <summary>
/// Adds a button to the dialog, its layout will be controled by the dialog
/// </summary>
/// <param name="button">Button to add.</param>
public void AddButton (Button button)
{
if (button == null)
return;
buttons.Add (button);
Add (button);
}
public override void LayoutSubviews ()
{
base.LayoutSubviews ();
@@ -38,7 +59,7 @@ namespace Terminal {
const int borderWidth = 2;
var start = (Frame.Width-borderWidth - buttonSpace) / 2;
var y = Frame.Height - borderWidth - 2 - maxHeight;
var y = Frame.Height - borderWidth - maxHeight;
foreach (var b in buttons) {
var bf = b.Frame;

View File

@@ -63,18 +63,18 @@ namespace Terminal {
static char [] whitespace = new char [] { ' ', '\t' };
string ClipAndJustify (string str)
static string ClipAndJustify (string str, int width, TextAlignment talign)
{
int slen = str.Length;
if (slen > Frame.Width)
return str.Substring (0, Frame.Width);
if (slen > width)
return str.Substring (0, width);
else {
if (textAlignment == TextAlignment.Justified) {
if (talign == TextAlignment.Justified) {
var words = str.Split (whitespace, StringSplitOptions.RemoveEmptyEntries);
int textCount = words.Sum ((arg) => arg.Length);
var spaces = (Frame.Width - textCount) / (words.Length - 1);
var extras = (Frame.Width - textCount) % words.Length;
var spaces = (width- textCount) / (words.Length - 1);
var extras = (width - textCount) % words.Length;
var s = new System.Text.StringBuilder ();
//s.Append ($"tc={textCount} sp={spaces},x={extras} - ");
for (int w = 0; w < words.Length; w++) {
@@ -97,18 +97,23 @@ namespace Terminal {
void Recalc ()
{
recalcPending = false;
lines.Clear ();
if (text.IndexOf ('\n') == -1) {
lines.Add (ClipAndJustify (text));
Recalc (text, lines, Frame.Width, textAlignment);
}
static void Recalc (string textStr, List<string> lineResult, int width, TextAlignment talign)
{
lineResult.Clear ();
if (textStr.IndexOf ('\n') == -1) {
lineResult.Add (ClipAndJustify (textStr, width, talign));
return;
}
int textLen = text.Length;
int textLen = textStr.Length;
int lp = 0;
for (int i = 0; i < textLen; i++) {
char c = text [i];
char c = textStr [i];
if (c == '\n') {
lines.Add (ClipAndJustify (text.Substring (lp, i - lp)));
lineResult.Add (ClipAndJustify (textStr.Substring (lp, i - lp), width, talign));
lp = i + 1;
}
}
@@ -150,6 +155,19 @@ namespace Terminal {
}
}
/// <summary>
/// Computes the number of lines needed to render the specified text by the Label control
/// </summary>
/// <returns>Number of lines.</returns>
/// <param name="text">Text, may contain newlines.</param>
/// <param name="width">The width for the text.</param>
public static int MeasureLines (string text, int width)
{
var result = new List<string> ();
Recalc (text, result, width, TextAlignment.Left);
return result.Count ();
}
/// <summary>
/// The text displayed by this widget.
/// </summary>

41
Views/MessageBox.cs Normal file
View File

@@ -0,0 +1,41 @@
using System;
namespace Terminal {
/// <summary>
/// Message box displays a modal message to the user, with a title, a message and a series of options that the user can choose from.
/// </summary>
public class MessageBox {
/// <summary>
/// Runs the dialog bo
/// </summary>
/// <returns>The index of the selected button, or -1 if the user pressed ESC to close the dialog.</returns>
/// <param name="width">Width for the window.</param>
/// <param name="height">Height for the window.</param>
/// <param name="title">Title for the query.</param>
/// <param name="message">Message to display, might contain multiple lines..</param>
/// <param name="buttons">Array of buttons to add.</param>
public static int Query (int width, int height, string title, string message, params string [] buttons)
{
int lines = Label.MeasureLines (message, width);
int clicked = -1, count = 0;
var d = new Dialog (title, width, height);
foreach (var s in buttons) {
int n = count++;
var b = new Button (s);
b.Clicked += delegate {
clicked = n;
d.Running = false;
};
d.AddButton (b);
}
if (message != null) {
var l = new Label ((width - 4 - message.Length) / 2, 0, message);
d.Add (l);
}
Application.Run (d);
return clicked;
}
}
}

View File

@@ -38,6 +38,12 @@ class Demo {
Application.Run (d);
}
static bool Quit ()
{
var n = MessageBox.Query (50, 5, "Quit Demo", "Are you sure you want to quit this demo?", "Yes", "No");
return n == 0;
}
public static Label ml;
static void Main ()
{
@@ -51,7 +57,7 @@ class Demo {
new MenuItem ("_New", "Creates new file", NewFile),
new MenuItem ("_Open", "", null),
new MenuItem ("_Close", "", null),
new MenuItem ("_Quit", "", () => { top.Running = false; })
new MenuItem ("_Quit", "", () => { if (Quit ()) top.Running = false; })
}),
new MenuBarItem ("_Edit", new MenuItem [] {
new MenuItem ("_Copy", "", null),