diff --git a/Terminal.Gui/FileServices/FileDialogStyle.cs b/Terminal.Gui/FileServices/FileDialogStyle.cs
index b8d55430f3..66ddc30892 100644
--- a/Terminal.Gui/FileServices/FileDialogStyle.cs
+++ b/Terminal.Gui/FileServices/FileDialogStyle.cs
@@ -21,7 +21,7 @@ public class FileDialogStyle {
/// Gets or sets the default value to use for .
/// This can be populated from .tui config files via
///
- [SerializableConfigurationProperty(Scope = typeof (SettingsScope))]
+ [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
public static bool DefaultUseColors { get; set; }
///
@@ -42,20 +42,20 @@ public class FileDialogStyle {
/// Gets or sets the class responsible for determining which symbol
/// to use to represent files and directories.
///
- public FileSystemIconProvider IconProvider { get; set;} = new FileSystemIconProvider();
+ public FileSystemIconProvider IconProvider { get; set; } = new FileSystemIconProvider ();
///
/// Gets or sets the class thatis responsible for determining which color
/// to use to represent files and directories when is
/// .
///
- public FileSystemColorProvider ColorProvider { get;set;} = new FileSystemColorProvider();
+ public FileSystemColorProvider ColorProvider { get; set; } = new FileSystemColorProvider ();
///
/// Gets or sets the culture to use (e.g. for number formatting).
/// Defaults to .
///
- public CultureInfo Culture {get;set;} = CultureInfo.CurrentUICulture;
+ public CultureInfo Culture { get; set; } = CultureInfo.CurrentUICulture;
///
/// Gets or sets the header text displayed in the Filename column of the files table.
@@ -80,12 +80,12 @@ public class FileDialogStyle {
///
/// Gets or sets the text displayed in the 'Search' text box when user has not supplied any input yet.
///
- public string SearchCaption { get; internal set; } = Strings.fdSearchCaption;
+ public string SearchCaption { get; set; } = Strings.fdSearchCaption;
///
/// Gets or sets the text displayed in the 'Path' text box when user has not supplied any input yet.
///
- public string PathCaption { get; internal set; } = Strings.fdPathCaption;
+ public string PathCaption { get; set; } = Strings.fdPathCaption;
///
/// Gets or sets the text on the 'Ok' button. Typically you may want to change this to
@@ -93,40 +93,52 @@ public class FileDialogStyle {
///
public string OkButtonText { get; set; } = "Ok";
+ ///
+ /// Gets or sets the text on the 'Cancel' button.
+ ///
+ public string CancelButtonText { get; set; } = "Cancel";
+
+ ///
+ /// Gets or sets whether to flip the order of the Ok and Cancel buttons. Defaults
+ /// to false (Ok button then Cancel button). Set to true to show Cancel button on
+ /// left then Ok button instead.
+ ///
+ public bool FlipOkCancelButtonLayoutOrder { get; set; }
+
///
/// Gets or sets error message when user attempts to select a file type that is not one of
///
- public string WrongFileTypeFeedback { get; internal set; } = Strings.fdWrongFileTypeFeedback;
+ public string WrongFileTypeFeedback { get; set; } = Strings.fdWrongFileTypeFeedback;
///
/// Gets or sets error message when user selects a directory that does not exist and
/// is and is .
///
- public string DirectoryMustExistFeedback { get; internal set; } = Strings.fdDirectoryMustExistFeedback;
+ public string DirectoryMustExistFeedback { get; set; } = Strings.fdDirectoryMustExistFeedback;
///
/// Gets or sets error message when user is
/// and user enters the name of an existing file (File system cannot have a folder with the same name as a file).
///
- public string FileAlreadyExistsFeedback { get; internal set; } = Strings.fdFileAlreadyExistsFeedback;
+ public string FileAlreadyExistsFeedback { get; set; } = Strings.fdFileAlreadyExistsFeedback;
///
/// Gets or sets error message when user selects a file that does not exist and
/// is and is .
///
- public string FileMustExistFeedback { get; internal set; } = Strings.fdFileMustExistFeedback;
+ public string FileMustExistFeedback { get; set; } = Strings.fdFileMustExistFeedback;
///
/// Gets or sets error message when user is
/// and user enters the name of an existing directory (File system cannot have a folder with the same name as a file).
///
- public string DirectoryAlreadyExistsFeedback { get; internal set; } = Strings.fdDirectoryAlreadyExistsFeedback;
+ public string DirectoryAlreadyExistsFeedback { get; set; } = Strings.fdDirectoryAlreadyExistsFeedback;
///
/// Gets or sets error message when user selects a file/dir that does not exist and
/// is and is .
///
- public string FileOrDirectoryMustExistFeedback { get; internal set; } = Strings.fdFileOrDirectoryMustExistFeedback;
+ public string FileOrDirectoryMustExistFeedback { get; set; } = Strings.fdFileOrDirectoryMustExistFeedback;
///
/// Gets the style settings for the table of files (in currently selected directory).
@@ -172,7 +184,7 @@ public FileDialogStyle (IFileSystem fileSystem)
}
- private Dictionary DefaultTreeRootGetter ()
+ private Dictionary DefaultTreeRootGetter ()
{
var roots = new Dictionary ();
try {
@@ -180,7 +192,7 @@ private Dictionary DefaultTreeRootGetter ()
var dir = _fileSystem.DirectoryInfo.New (d);
- if (!roots.ContainsKey(dir)) {
+ if (!roots.ContainsKey (dir)) {
roots.Add (dir, d);
}
}
@@ -194,14 +206,14 @@ private Dictionary DefaultTreeRootGetter ()
try {
var path = Environment.GetFolderPath (special);
- if(string.IsNullOrWhiteSpace (path)) {
+ if (string.IsNullOrWhiteSpace (path)) {
continue;
}
var dir = _fileSystem.DirectoryInfo.New (path);
if (!roots.ContainsKey (dir) && dir.Exists) {
- roots.Add (dir, special.ToString());
+ roots.Add (dir, special.ToString ());
}
} catch (Exception) {
// Special file exists but contents are unreadable (permissions?)
diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs
index e71fdf9c68..db98d5ee25 100644
--- a/Terminal.Gui/Views/FileDialog.cs
+++ b/Terminal.Gui/Views/FileDialog.cs
@@ -105,7 +105,7 @@ public partial class FileDialog : Dialog {
private int currentSortColumn;
private bool currentSortIsAsc = true;
- private Dictionary _treeRoots = new Dictionary();
+ private Dictionary _treeRoots = new Dictionary ();
///
/// Event fired when user attempts to confirm a selection (or multi selection).
@@ -142,11 +142,7 @@ public FileDialog (IFileSystem fileSystem)
this.btnOk = new Button (Style.OkButtonText) {
Y = Pos.AnchorEnd (1),
- X = Pos.Function (() =>
- this.Bounds.Width
- - btnOk.Bounds.Width
- // TODO: Fiddle factor, seems the Bounds are wrong for someone
- - 2)
+ X = Pos.Function (CalculateOkButtonPosX)
};
this.btnOk.Clicked += (s, e) => this.Accept (true);
this.btnOk.KeyPress += (s, k) => {
@@ -156,14 +152,7 @@ public FileDialog (IFileSystem fileSystem)
this.btnCancel = new Button (Strings.btnCancel) {
Y = Pos.AnchorEnd (1),
- X = Pos.Function (() =>
- this.Bounds.Width
- - btnOk.Bounds.Width
- - btnCancel.Bounds.Width
- - 1
- // TODO: Fiddle factor, seems the Bounds are wrong for someone
- - 2
- )
+ X = Pos.Right (btnOk) + 1
};
this.btnCancel.KeyPress += (s, k) => {
this.NavigateIf (k, Key.CursorLeft, this.btnToggleSplitterCollapse);
@@ -188,7 +177,6 @@ public FileDialog (IFileSystem fileSystem)
this.tbPath = new TextField {
Width = Dim.Fill (0),
- Caption = Style.PathCaption,
CaptionColor = Color.Black
};
this.tbPath.KeyPress += (s, k) => {
@@ -285,7 +273,6 @@ public FileDialog (IFileSystem fileSystem)
tbFind = new TextField {
X = Pos.Right (this.btnToggleSplitterCollapse) + 1,
- Caption = Style.SearchCaption,
CaptionColor = Color.Black,
Width = 30,
Y = Pos.AnchorEnd (1),
@@ -373,17 +360,27 @@ public FileDialog (IFileSystem fileSystem)
this.Add (this.splitContainer);
}
+ private int CalculateOkButtonPosX ()
+ {
+ return this.Bounds.Width
+ - btnOk.Bounds.Width
+ - btnCancel.Bounds.Width
+ - 1
+ // TODO: Fiddle factor, seems the Bounds are wrong for someone
+ - 2;
+ }
+
private string AspectGetter (object o)
{
var fsi = (IFileSystemInfo)o;
- if(o is IDirectoryInfo dir && _treeRoots.ContainsKey(dir)) {
+ if (o is IDirectoryInfo dir && _treeRoots.ContainsKey (dir)) {
// Directory has a special name e.g. 'Pictures'
return _treeRoots [dir];
}
- return (Style.IconProvider.GetIconWithOptionalSpace(fsi) + fsi.Name).Trim();
+ return (Style.IconProvider.GetIconWithOptionalSpace (fsi) + fsi.Name).Trim ();
}
private void OnTableViewMouseClick (object sender, MouseEventEventArgs e)
@@ -644,11 +641,28 @@ public override void OnLoaded ()
// May have been updated after instance was constructed
this.btnOk.Text = Style.OkButtonText;
+ this.btnCancel.Text = Style.CancelButtonText;
this.btnUp.Text = this.GetUpButtonText ();
this.btnBack.Text = this.GetBackButtonText ();
this.btnForward.Text = this.GetForwardButtonText ();
this.btnToggleSplitterCollapse.Text = this.GetToggleSplitterText (false);
+ if (Style.FlipOkCancelButtonLayoutOrder) {
+ btnCancel.X = Pos.Function (this.CalculateOkButtonPosX);
+ btnOk.X = Pos.Right (btnCancel) + 1;
+
+
+ // Flip tab order too for consistency
+ var p1 = this.btnOk.TabIndex;
+ var p2 = this.btnCancel.TabIndex;
+
+ this.btnOk.TabIndex = p2;
+ this.btnCancel.TabIndex = p1;
+ }
+
+ tbPath.Caption = Style.PathCaption;
+ tbFind.Caption = Style.SearchCaption;
+
tbPath.Autocomplete.ColorScheme.Normal = Attribute.Make (Color.Black, tbPath.ColorScheme.Normal.Background);
_treeRoots = Style.TreeRootGetter ();
@@ -700,7 +714,7 @@ public override void OnLoaded ()
// if no path has been provided
if (this.tbPath.Text.Length <= 0) {
- this.tbPath.Text = Environment.CurrentDirectory;
+ this.Path = Environment.CurrentDirectory;
}
// to streamline user experience and allow direct typing of paths
@@ -803,7 +817,7 @@ private void Accept (IEnumerable toMultiAccept)
.Select (s => s.FileSystemInfo.FullName)
.ToList ().AsReadOnly ();
- this.tbPath.Text = this.MultiSelected.Count == 1 ? this.MultiSelected [0] : string.Empty;
+ this.Path = this.MultiSelected.Count == 1 ? this.MultiSelected [0] : string.Empty;
FinishAccept ();
}
@@ -816,7 +830,7 @@ private void Accept (IFileInfo f)
return;
}
- this.tbPath.Text = f.FullName;
+ this.Path = f.FullName;
if (AllowsMultipleSelection) {
this.MultiSelected = new List { f.FullName }.AsReadOnly ();
@@ -895,7 +909,7 @@ private void TreeView_SelectionChanged (object sender, SelectionChangedEventArgs
return;
}
- this.tbPath.Text = e.NewValue.FullName;
+ this.Path = e.NewValue.FullName;
}
private void UpdateNavigationVisibility ()
@@ -931,7 +945,7 @@ private void TableView_SelectedCellChanged (object sender, SelectedCellChangedEv
try {
this.pushingState = true;
- this.tbPath.Text = dest.FullName;
+ this.Path = dest.FullName;
this.State.Selected = stats;
this.tbPath.Autocomplete.ClearSuggestions ();
@@ -1134,12 +1148,10 @@ private void PushState (FileDialogState newState, bool addCurrentStateToHistory,
this.tbPath.Autocomplete.ClearSuggestions ();
if (pathText != null) {
- this.tbPath.Text = pathText;
- this.tbPath.MoveEnd ();
+ this.Path = pathText;
} else
if (setPathText) {
- this.tbPath.Text = newState.Directory.FullName;
- this.tbPath.MoveEnd ();
+ this.Path = newState.Directory.FullName;
}
this.State = newState;
@@ -1185,13 +1197,13 @@ private ColorScheme ColorGetter (CellColorGetterArgs args)
}
- var color = Style.ColorProvider.GetTrueColor(stats.FileSystemInfo)
- ?? TrueColor.FromConsoleColor(Color.White);
- var black = TrueColor.FromConsoleColor(Color.Black);
+ var color = Style.ColorProvider.GetTrueColor (stats.FileSystemInfo)
+ ?? TrueColor.FromConsoleColor (Color.White);
+ var black = TrueColor.FromConsoleColor (Color.Black);
// TODO: Add some kind of cache for this
- return new ColorScheme{
- Normal = new Attribute (color,black),
+ return new ColorScheme {
+ Normal = new Attribute (color, black),
HotNormal = new Attribute (color, black),
Focus = new Attribute (black, color),
HotFocus = new Attribute (black, color),
diff --git a/UICatalog/Scenarios/FileDialogExamples.cs b/UICatalog/Scenarios/FileDialogExamples.cs
index e110d27a24..8a0fcf11ec 100644
--- a/UICatalog/Scenarios/FileDialogExamples.cs
+++ b/UICatalog/Scenarios/FileDialogExamples.cs
@@ -25,6 +25,9 @@ public class FileDialogExamples : Scenario {
private RadioGroup rgIcons;
private RadioGroup rgAllowedTypes;
+ private TextField tbOkButton;
+ private TextField tbCancelButton;
+ private CheckBox cbFlipButtonOrder;
public override void Setup ()
{
var y = 0;
@@ -110,6 +113,25 @@ public override void Setup ()
rgAllowedTypes.RadioLabels = new string [] { "Any", "Csv (Recommended)", "Csv (Strict)" };
Win.Add (rgAllowedTypes);
+ y = 5;
+ x = 45;
+
+ Win.Add (new LineView (Orientation.Vertical) {
+ X = x++,
+ Y = y + 1,
+ Height = 4
+ });
+ Win.Add (new Label ("Buttons") { X = x++, Y = y++ });
+
+ Win.Add (new Label ("Ok Text:") { X = x, Y = y++ });
+ tbOkButton = new TextField () { X = x, Y = y++, Width = 12 };
+ Win.Add (tbOkButton);
+ Win.Add (new Label ("Cancel Text:") { X = x, Y = y++ });
+ tbCancelButton = new TextField () { X = x, Y = y++, Width = 12 };
+ Win.Add (tbCancelButton);
+ cbFlipButtonOrder = new CheckBox ("Flip Order") { X = x, Y = y++ };
+ Win.Add (cbFlipButtonOrder);
+
var btn = new Button ($"Run Dialog") {
X = 1,
Y = 9
@@ -165,7 +187,7 @@ rgOpenMode.RadioLabels [rgOpenMode.SelectedItem].ToString ()),
if (cbDrivesOnlyInTree.Checked ?? false) {
fd.Style.TreeRootGetter = () => {
- return System.Environment.GetLogicalDrives ().ToDictionary(dirInfoFactory.New,k=>k);
+ return System.Environment.GetLogicalDrives ().ToDictionary (dirInfoFactory.New, k => k);
};
}
@@ -178,6 +200,16 @@ rgOpenMode.RadioLabels [rgOpenMode.SelectedItem].ToString ()),
}
+ if (!string.IsNullOrWhiteSpace (tbOkButton.Text)) {
+ fd.Style.OkButtonText = tbOkButton.Text;
+ }
+ if (!string.IsNullOrWhiteSpace (tbCancelButton.Text)) {
+ fd.Style.CancelButtonText = tbCancelButton.Text;
+ }
+ if (cbFlipButtonOrder.Checked ?? false) {
+ fd.Style.FlipOkCancelButtonLayoutOrder = true;
+ }
+
Application.Run (fd);
if (fd.Canceled) {
diff --git a/UnitTests/FileServices/FileDialogTests.cs b/UnitTests/FileServices/FileDialogTests.cs
index 88fe00230d..fb1b28b3fa 100644
--- a/UnitTests/FileServices/FileDialogTests.cs
+++ b/UnitTests/FileServices/FileDialogTests.cs
@@ -398,7 +398,7 @@ public void TestDirectoryContents_Linux ()
│ │
│ │
│ │
-│{CM.Glyphs.LeftBracket} ►► {CM.Glyphs.RightBracket} Enter Search {CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket} {CM.Glyphs.LeftBracket} Ok {CM.Glyphs.RightBracket} │
+│{CM.Glyphs.LeftBracket} ►► {CM.Glyphs.RightBracket} Enter Search {CM.Glyphs.LeftBracket} Ok {CM.Glyphs.RightBracket} {CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket} │
└──────────────────────────────────────────────────────────────────┘
";
TestHelpers.AssertDriverContentsAre (expected, output, true);
@@ -434,7 +434,7 @@ public void TestDirectoryContents_Windows ()
││mybinary.exe│7.00 bytes│2001-01-01T11:44:42 │.exe ││
│ │
│ │
-│{CM.Glyphs.LeftBracket} ►► {CM.Glyphs.RightBracket} Enter Search {CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket} {CM.Glyphs.LeftBracket} Ok {CM.Glyphs.RightBracket} │
+│{CM.Glyphs.LeftBracket} ►► {CM.Glyphs.RightBracket} Enter Search {CM.Glyphs.LeftBracket} Ok {CM.Glyphs.RightBracket} {CM.Glyphs.LeftBracket} Cancel {CM.Glyphs.RightBracket} │
└──────────────────────────────────────────────────────────────────┘
";
TestHelpers.AssertDriverContentsAre (expected, output, true);