Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Text Alignments. and fixes #583. Changed Clicked from Action to EventHandler per tenets. #621

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Example/demo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ static void NewFile ()
{
var d = new Dialog (
"New File", 50, 20,
new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } },
new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } });
new Button ("Ok", is_default: true) { Clicked = (o, e) => { Application.RequestStop (); } },
new Button ("Cancel") { Clicked = (o, e) => { Application.RequestStop (); } });
ml2 = new Label (1, 1, "Mouse Debug Line");
d.Add (ml2);
Application.Run (d);
Expand Down Expand Up @@ -391,8 +391,8 @@ static void Save ()
static void ListSelectionDemo (bool multiple)
{
var d = new Dialog ("Selection Demo", 60, 20,
new Button ("Ok", is_default: true) { Clicked = () => { Application.RequestStop (); } },
new Button ("Cancel") { Clicked = () => { Application.RequestStop (); } });
new Button ("Ok", is_default: true) { Clicked = (o, e) => { Application.RequestStop (); } },
new Button ("Cancel") { Clicked = (o, e) => { Application.RequestStop (); } });

var animals = new List<string> () { "Alpaca", "Llama", "Lion", "Shark", "Goat" };
var msg = new Label ("Use space bar or control-t to toggle selection") {
Expand Down Expand Up @@ -450,7 +450,7 @@ private static void OnKeyDownPressUpDemo ()
{
var container = new Dialog (
"KeyDown & KeyPress & KeyUp demo", 80, 20,
new Button ("Close") { Clicked = () => { Application.RequestStop (); } }) {
new Button ("Close") { Clicked = (o, e) => { Application.RequestStop (); } }) {
Width = Dim.Fill (),
Height = Dim.Fill (),
};
Expand Down
38 changes: 19 additions & 19 deletions FSharpExample/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ type Demo() = class end
let ShowTextAlignments() =
let mutable container = new Dialog(
ustr "Text Alignments", 50, 20,
new Button (ustr "Ok", true, Clicked = Action(Application.RequestStop)),
new Button (ustr "Cancel", true, Clicked = Action(Application.RequestStop))
new Button (ustr "Ok", true, Clicked = fun o e -> Application.RequestStop ()),
new Button (ustr "Cancel", true, Clicked = fun o e -> Application.RequestStop ())
)
let mutable (i : int) = 0
let mutable (txt : string) = "Hello world, how are you doing today"
Expand Down Expand Up @@ -166,8 +166,8 @@ type Demo() = class end
()
let NewFile() =
let mutable d = new Dialog (ustr "New File", 50, 20,
new Button (ustr "Ok", true, Clicked = Action(Application.RequestStop)),
new Button (ustr "Cancel", true, Clicked = Action(Application.RequestStop))
new Button (ustr "Ok", true, Clicked = fun o e -> Application.RequestStop ()),
new Button (ustr "Cancel", true, Clicked = fun o e -> Application.RequestStop ())
)
ml2 <- new Label(1, 1, ustr "Mouse Debug Line")
d.Add (ml2)
Expand Down Expand Up @@ -202,18 +202,18 @@ type Demo() = class end
Application.Run (ntop)

let Quit() =
let mutable n = MessageBox.Query (50, 7, "Quit Demo", "Are you sure you want to quit this demo?", "Yes", "No")
let mutable n = MessageBox.Query (50, 7, ustr "Quit Demo", ustr "Are you sure you want to quit this demo?", ustr "Yes", ustr "No")
n = 0

let Close() =
MessageBox.ErrorQuery (50, 7, "Error", "There is nothing to close", "Ok")
MessageBox.ErrorQuery (50, 7, ustr "Error", ustr "There is nothing to close", ustr "Ok")
|> ignore

let Open() =
let mutable d = new OpenDialog (ustr "Open", ustr "Open a file", AllowsMultipleSelection = true)
Application.Run (d)
if not d.Canceled
then MessageBox.Query (50, 7, "Selected File", (String.Join (", ", d.FilePaths)), "Ok") |> ignore
then MessageBox.Query (50, 7, ustr "Selected File", ustr (String.Join (", ", d.FilePaths)), ustr "Ok") |> ignore

let ShowHex(top : Toplevel) =
let mutable tframe = top.Frame
Expand Down Expand Up @@ -255,14 +255,14 @@ type Demo() = class end
let mutable (flags : BindingFlags) = BindingFlags.Public ||| BindingFlags.Static
let mutable (minfo : MethodInfo) = typeof<MenuItemDetails>.GetMethod ("Instance", flags)
let mutable (mid : Delegate) = Delegate.CreateDelegate (typeof<MenuItemDelegate>, minfo)
MessageBox.Query (70, 7, (mi.Title.ToString ()),
((sprintf "%O selected. Is from submenu: %O" (mi.Title.ToString ())) (mi.GetMenuBarItem ())), "Ok")
MessageBox.Query (70, 7, ustr (mi.Title.ToString ()),
ustr ((sprintf "%O selected. Is from submenu: %O" (mi.Title.ToString ())) (mi.GetMenuBarItem ())), ustr "Ok")
|> ignore

let MenuKeysStyle_Toggled(e : EventArgs) =
let MenuKeysStyle_Toggled(e : bool) =
menu.UseKeysUpDownAsKeysLeftRight <- menuKeysStyle.Checked

let MenuAutoMouseNav_Toggled(e : EventArgs) =
let MenuAutoMouseNav_Toggled(e : bool) =
menu.WantMousePositionReports <- menuAutoMouseNav.Checked

let Copy() =
Expand All @@ -284,13 +284,13 @@ type Demo() = class end
()

let Help() =
MessageBox.Query (50, 7, "Help", "This is a small help\nBe kind.", "Ok")
MessageBox.Query (50, 7, ustr "Help", ustr "This is a small help\nBe kind.", ustr "Ok")
|> ignore

let ListSelectionDemo(multiple : System.Boolean) =
let mutable d = new Dialog (ustr "Selection Demo", 60, 20,
new Button (ustr "Ok", true, Clicked = fun () -> Application.RequestStop ()),
new Button (ustr "Cancel", Clicked = fun () -> Application.RequestStop ())
new Button (ustr "Ok", true, Clicked = fun o e -> Application.RequestStop ()),
new Button (ustr "Cancel", Clicked = fun o e -> Application.RequestStop ())
)
let mutable animals = new List<string> ()
animals.AddRange([|"Alpaca"; "Llama"; "Lion"; "Shark"; "Goat"|])
Expand Down Expand Up @@ -319,11 +319,11 @@ type Demo() = class end
i <- i + 1
i
()
MessageBox.Query (60, 10, "Selected Animals", (if result = "" then "No animals selected" else result), "Ok") |> ignore
MessageBox.Query (60, 10, ustr "Selected Animals", ustr (if result = "" then "No animals selected" else result), ustr "Ok") |> ignore

let OnKeyDownPressUpDemo() =
let mutable container = new Dialog (ustr "KeyDown & KeyPress & KeyUp demo", 80, 20,
new Button (ustr "Close", Clicked = fun () -> Application.RequestStop ()),
new Button (ustr "Close", Clicked = fun o e -> Application.RequestStop ()),
Width = Dim.Fill (),
Height = Dim.Fill ()
)
Expand Down Expand Up @@ -395,11 +395,11 @@ type Demo() = class end
[|new MenuItem(ustr "SubMenu1Item_1", new MenuBarItem([|new MenuItem(ustr "SubMenu2Item_1",
new MenuBarItem([|new MenuItem(ustr "SubMenu3Item_1", new MenuBarItem([|(menuItems.[2])|]))|]))|]))|]);
new MenuBarItem(ustr "_About...", "Demonstrates top-level menu item",
(fun () -> MessageBox.ErrorQuery (50, 7, "About Demo", "This is a demo app for gui.cs", "Ok") |> ignore))|])
(fun () -> MessageBox.ErrorQuery (50, 7, ustr "About Demo", ustr "This is a demo app for gui.cs", ustr "Ok") |> ignore))|])
menuKeysStyle <- new CheckBox(3, 25, ustr "UseKeysUpDownAsKeysLeftRight", true)
menuKeysStyle.Toggled.Add(MenuKeysStyle_Toggled)
menuKeysStyle.Toggled.Add (MenuKeysStyle_Toggled)
menuAutoMouseNav <- new CheckBox(40, 25, ustr "UseMenuAutoNavigation", true)
menuAutoMouseNav.Toggled.Add(MenuAutoMouseNav_Toggled)
menuAutoMouseNav.Toggled.Add (MenuAutoMouseNav_Toggled)
ShowEntries (win)
let mutable (count : int) = 0
ml <- new Label(new Rect(3, 17, 47, 1), ustr "Mouse: ")
Expand Down
107 changes: 92 additions & 15 deletions Terminal.Gui/Views/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class Button : View {
Rune hot_key;
int hot_pos = -1;
bool is_default;
TextAlignment textAlignment = TextAlignment.Centered;

/// <summary>
/// Gets or sets whether the <see cref="Button"/> is the default action to activate in a dialog.
Expand All @@ -45,14 +46,14 @@ public bool IsDefault {
}

/// <summary>
/// Clicked <see cref="Action"/>, raised when the button is clicked.
/// Clicked <see cref="EventHandler"/>, raised when the button is clicked.
/// </summary>
/// <remarks>
/// Client code can hook up to this event, it is
/// raised when the button is activated either with
/// the mouse or the keyboard.
/// </remarks>
public Action Clicked;
public EventHandler Clicked;

/// <summary>
/// Initializes a new instance of <see cref="Button"/> using <see cref="LayoutStyle.Computed"/> layout.
Expand Down Expand Up @@ -145,6 +146,15 @@ public ustring Text {
}
}

///<inheritdoc/>
public TextAlignment TextAlignment {
get => textAlignment;
set {
textAlignment = value;
SetNeedsDisplay ();
}
}

internal void Update ()
{
if (IsDefault)
Expand Down Expand Up @@ -176,31 +186,91 @@ internal void Update ()
SetNeedsDisplay ();
}

int c_hot_pos;

///<inheritdoc/>
public override void Redraw (Rect bounds)
{
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
Move (0, 0);
Driver.AddStr (shown_text);

if (hot_pos != -1) {
Move (hot_pos, 0);
var caption = shown_text;
c_hot_pos = hot_pos;
int start;

if (Frame.Width > shown_text.Length + 1) {
switch (TextAlignment) {
case TextAlignment.Left:
caption += new string (' ', Frame.Width - caption.Length);
break;
case TextAlignment.Right:
start = Frame.Width - caption.Length;
caption = $"{new string (' ', Frame.Width - caption.Length)}{caption}";
if (c_hot_pos > -1) {
c_hot_pos += start;
}
break;
case TextAlignment.Centered:
start = Frame.Width / 2 - caption.Length / 2;
caption = $"{new string (' ', start)}{caption}{new string (' ', Frame.Width - caption.Length - start)}";
if (c_hot_pos > -1) {
c_hot_pos += start;
}
break;
case TextAlignment.Justified:
var words = caption.ToString ().Split (new string [] { " " }, StringSplitOptions.RemoveEmptyEntries);
var wLen = GetWordsLength (words);
var space = (Frame.Width - wLen) / (caption.Length - wLen);
caption = "";
for (int i = 0; i < words.Length; i++) {
if (i == words.Length - 1) {
caption += new string (' ', Frame.Width - caption.Length - 1);
caption += words [i];
} else {
caption += words [i];
}
if (i < words.Length - 1) {
caption += new string (' ', space);
}
}
if (c_hot_pos > -1) {
c_hot_pos += space - 1;
}
break;
}
}

Driver.AddStr (caption);

if (c_hot_pos != -1) {
Move (c_hot_pos, 0);
Driver.SetAttribute (HasFocus ? ColorScheme.HotFocus : ColorScheme.HotNormal);
Driver.AddRune (hot_key);
}
}

int GetWordsLength (string[] words)
{
int length = 0;

for (int i = 0; i < words.Length; i++) {
length += words [i].Length;
}

return length;
}

///<inheritdoc/>
public override void PositionCursor ()
{
Move (hot_pos == -1 ? 1 : hot_pos, 0);
Move (c_hot_pos == -1 ? 1 : c_hot_pos, 0);
}

bool CheckKey (KeyEvent key)
{
if (Char.ToUpper ((char)key.KeyValue) == hot_key) {
this.SuperView.SetFocus (this);
Clicked?.Invoke ();
OnClicked ();
return true;
}
return false;
Expand All @@ -219,8 +289,7 @@ public override bool ProcessHotKey (KeyEvent kb)
public override bool ProcessColdKey (KeyEvent kb)
{
if (IsDefault && kb.KeyValue == '\n') {
if (Clicked != null)
Clicked ();
OnClicked ();
return true;
}
return CheckKey (kb);
Expand All @@ -231,8 +300,7 @@ public override bool ProcessKey (KeyEvent kb)
{
var c = kb.KeyValue;
if (c == '\n' || c == ' ' || Rune.ToUpper ((uint)c) == hot_key) {
if (Clicked != null)
Clicked ();
OnClicked ();
return true;
}
return base.ProcessKey (kb);
Expand All @@ -242,14 +310,23 @@ public override bool ProcessKey (KeyEvent kb)
public override bool MouseEvent (MouseEvent me)
{
if (me.Flags == MouseFlags.Button1Clicked) {
SuperView.SetFocus (this);
SetNeedsDisplay ();
if (!HasFocus) {
SuperView.SetFocus (this);
SetNeedsDisplay ();
}

if (Clicked != null)
Clicked ();
OnClicked ();
return true;
}
return false;
}

/// <summary>
/// Virtual method that will invoke the Clicked event handler.
/// </summary>
public virtual void OnClicked ()
{
Clicked?.Invoke (this, EventArgs.Empty);
}
}
}
4 changes: 2 additions & 2 deletions Terminal.Gui/Views/Label.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ public static int MeasureLines (ustring text, int width)
}

/// <summary>
/// Computes the the max width of a line or multilines needed to render by the Label control
/// Computes the max width of a line or multilines needed to render by the Label control
/// </summary>
/// <returns>Max width of lines.</returns>
/// <param name="text">Text, may contain newlines.</param>
Expand All @@ -285,7 +285,7 @@ public virtual ustring Text {
}

/// <summary>
/// Controls the text-alignemtn property of the label, changing it will redisplay the <see cref="Label"/>.
/// Controls the text-alignment property of the label, changing it will redisplay the <see cref="Label"/>.
/// </summary>
/// <value>The text alignment.</value>
public TextAlignment TextAlignment {
Expand Down
4 changes: 2 additions & 2 deletions Terminal.Gui/Windows/FileDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ public FileDialog (ustring title, ustring prompt, ustring nameFieldLabel, ustrin
dirListView.FileChanged = (file) => nameEntry.Text = file;

this.cancel = new Button ("Cancel");
this.cancel.Clicked += () => {
this.cancel.Clicked += (o, e) => {
canceled = true;
Application.RequestStop ();
};
Expand All @@ -486,7 +486,7 @@ public FileDialog (ustring title, ustring prompt, ustring nameFieldLabel, ustrin
this.prompt = new Button (prompt) {
IsDefault = true,
};
this.prompt.Clicked += () => {
this.prompt.Clicked += (o, e) => {
dirListView.ExecuteSelection ();
canceled = false;
Application.RequestStop ();
Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Windows/MessageBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static int QueryFull (bool useErrorColors, int width, int height, ustring title,
int clicked = -1;
for (int n = 0; n < buttonList.Count; n++) {
int buttonId = n;
buttonList [n].Clicked += () => {
buttonList [n].Clicked += (o, e) => {
clicked = buttonId;
Application.RequestStop ();
};
Expand Down
Loading