Merge branch 'filedialog-features' into all-pull-request-at-once

This commit is contained in:
BDisp
2020-03-10 13:55:43 +00:00
5 changed files with 252 additions and 60 deletions

View File

@@ -52,4 +52,4 @@
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
</Project>

View File

@@ -222,10 +222,13 @@ static class Demo {
public static void Open ()
{
var d = new OpenDialog ("Open", "Open a file");
var d = new OpenDialog ("Open", "Open a file") {
AllowsMultipleSelection = true
};
Application.Run (d);
MessageBox.Query (50, 7, "Selected File", string.Join (", ", d.FilePaths), "Ok");
if (!d.Canceled)
MessageBox.Query(50, 7, "Selected File", string.Join(", ", d.FilePaths), "Ok");
}
public static void ShowHex (Toplevel top)

View File

@@ -23,11 +23,13 @@ namespace Terminal.Gui {
internal bool canChooseFiles = true;
internal bool canChooseDirectories = false;
internal bool allowsMultipleSelection = false;
FileDialog host;
public DirListView ()
public DirListView (FileDialog host)
{
infos = new List<(string,bool,bool)> ();
CanFocus = true;
this.host = host;
}
bool IsAllowed (FileSystemInfo fsi)
@@ -71,6 +73,70 @@ namespace Terminal.Gui {
Move (0, selected - top);
}
int lastSelected;
bool shiftOnWheel;
public override bool MouseEvent (MouseEvent me)
{
if ((me.Flags & (MouseFlags.Button1Clicked | MouseFlags.Button1DoubleClicked |
MouseFlags.WheeledUp | MouseFlags.WheeledDown)) == 0)
return false;
if (!HasFocus)
SuperView.SetFocus (this);
if (infos == null)
return false;
if (me.Y + top >= infos.Count)
return true;
int lastSelectedCopy = shiftOnWheel ? lastSelected : selected;
lastSelected = selected;
selected = top + me.Y;
switch (me.Flags) {
case MouseFlags.Button1DoubleClicked:
if (ExecuteSelection ()) {
host.canceled = false;
Application.RequestStop ();
}
return true;
case MouseFlags.Button1Clicked | MouseFlags.ButtonShift:
if (shiftOnWheel)
lastSelected = lastSelectedCopy;
shiftOnWheel = false;
PerformMultipleSelection (lastSelected);
return true;
case MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl:
PerformMultipleSelection ();
return true;
case MouseFlags.WheeledUp:
selected = lastSelected;
MoveUp ();
return true;
case MouseFlags.WheeledDown:
selected = lastSelected;
MoveDown ();
return true;
case MouseFlags.WheeledUp | MouseFlags.ButtonShift:
selected = lastSelected;
lastSelected = lastSelectedCopy;
shiftOnWheel = true;
MoveUp ();
return true;
case MouseFlags.WheeledDown | MouseFlags.ButtonShift:
selected = lastSelected;
lastSelected = lastSelectedCopy;
shiftOnWheel = true;
MoveDown ();
return true;
}
SelectionChanged ();
SetNeedsDisplay ();
return true;
}
void DrawString (int line, string str)
{
var f = Frame;
@@ -91,7 +157,7 @@ namespace Terminal.Gui {
}
for (; used < width; used++) {
Driver.AddRune (' ');
}
}
}
public override void Redraw (Rect region)
@@ -123,7 +189,7 @@ namespace Terminal.Gui {
if (allowsMultipleSelection)
Driver.AddRune (fi.Item3 ? '*' : ' ');
if (fi.Item2)
Driver.AddRune ('/');
else
@@ -138,35 +204,38 @@ namespace Terminal.Gui {
void SelectionChanged ()
{
if (FilePaths.Count > 0)
FileChanged?.Invoke (string.Join (", ", GetFilesName (FilePaths)));
else
FileChanged?.Invoke (infos [selected].Item2 ? "" : Path.GetFileName (infos [selected].Item1));
if (SelectedChanged != null) {
var sel = infos [selected];
SelectedChanged ((sel.Item1, sel.Item2));
}
}
List<string> GetFilesName (IReadOnlyList<string> files)
{
List<string> filesName = new List<string> ();
foreach (var file in files) {
filesName.Add (Path.GetFileName (file));
}
return filesName;
}
public override bool ProcessKey (KeyEvent keyEvent)
{
switch (keyEvent.Key) {
case Key.CursorUp:
case Key.ControlP:
if (selected > 0) {
selected--;
if (selected < top)
top = selected;
SelectionChanged ();
SetNeedsDisplay ();
}
MoveUp ();
return true;
case Key.CursorDown:
case Key.ControlN:
if (selected + 1 < infos.Count) {
selected++;
if (selected >= top + Frame.Height)
top++;
SelectionChanged ();
SetNeedsDisplay ();
}
MoveDown ();
return true;
case Key.ControlV:
@@ -187,22 +256,10 @@ namespace Terminal.Gui {
return true;
case Key.Enter:
var isDir = infos [selected].Item2;
if (isDir) {
Directory = Path.GetFullPath (Path.Combine (Path.GetFullPath (Directory.ToString ()), infos [selected].Item1));
if (DirectoryChanged != null)
DirectoryChanged (Directory);
} else {
if (FileChanged != null)
FileChanged (infos [selected].Item1);
if (canChooseFiles) {
// Let the OK handler take it over
return false;
}
// No files allowed, do not let the default handler take it.
}
return true;
if (ExecuteSelection ())
return false;
else
return true;
case Key.PageUp:
n = (selected - Frame.Height);
@@ -217,21 +274,97 @@ namespace Terminal.Gui {
return true;
case Key.Space:
case Key.ControlT:
if (allowsMultipleSelection) {
if ((canChooseFiles && infos [selected].Item2 == false) ||
(canChooseDirectories && infos [selected].Item2 &&
infos [selected].Item1 != "..")){
infos [selected] = (infos [selected].Item1, infos [selected].Item2, !infos [selected].Item3);
SelectionChanged ();
SetNeedsDisplay ();
}
}
case Key.ControlT:
PerformMultipleSelection ();
return true;
case Key.Home:
MoveFirst ();
return true;
case Key.End:
MoveLast ();
return true;
}
return base.ProcessKey (keyEvent);
}
private void MoveLast ()
{
selected = infos.Count - 1;
top = infos.Count () - 1;
SelectionChanged ();
SetNeedsDisplay ();
}
private void MoveFirst ()
{
selected = 0;
top = 0;
SelectionChanged ();
SetNeedsDisplay ();
}
private void MoveDown ()
{
if (selected + 1 < infos.Count) {
selected++;
if (selected >= top + Frame.Height)
top++;
SelectionChanged ();
SetNeedsDisplay ();
}
}
private void MoveUp ()
{
if (selected > 0) {
selected--;
if (selected < top)
top = selected;
SelectionChanged ();
SetNeedsDisplay ();
}
}
internal bool ExecuteSelection ()
{
var isDir = infos [selected].Item2;
if (isDir) {
Directory = Path.GetFullPath (Path.Combine (Path.GetFullPath (Directory.ToString ()), infos [selected].Item1));
DirectoryChanged?.Invoke (Directory);
} else {
FileChanged?.Invoke (infos [selected].Item1);
if (canChooseFiles) {
// Ensures that at least one file is selected.
if (FilePaths.Count == 0)
PerformMultipleSelection ();
// Let the OK handler take it over
return true;
}
// No files allowed, do not let the default handler take it.
}
return false;
}
private void PerformMultipleSelection (int? firstSelected = null)
{
if (allowsMultipleSelection) {
int first = Math.Min (firstSelected ?? selected, selected);
int last = Math.Max (selected, firstSelected ?? selected);
for (int i = first; i <= last; i++) {
if ((canChooseFiles && infos [i].Item2 == false) ||
(canChooseDirectories && infos [i].Item2 &&
infos [i].Item1 != "..")) {
infos [i] = (infos [i].Item1, infos [i].Item2, !infos [i].Item3);
}
}
SelectionChanged ();
SetNeedsDisplay ();
}
}
string [] allowedFileTypes;
public string [] AllowedFileTypes {
get => allowedFileTypes;
@@ -306,18 +439,16 @@ namespace Terminal.Gui {
};
Add (this.nameFieldLabel, nameEntry);
dirListView = new DirListView () {
dirListView = new DirListView (this) {
X = 1,
Y = 3 + msgLines + 2,
Width = Dim.Fill () - 2,
Width = Dim.Fill () - 3,
Height = Dim.Fill () - 2,
};
DirectoryPath = Path.GetFullPath (Environment.CurrentDirectory);
Add (dirListView);
dirListView.DirectoryChanged = (dir) => dirEntry.Text = dir;
dirListView.FileChanged = (file) => {
nameEntry.Text = file;
};
dirListView.FileChanged = (file) => nameEntry.Text = file;
this.cancel = new Button ("Cancel");
this.cancel.Clicked += () => {
@@ -330,6 +461,7 @@ namespace Terminal.Gui {
IsDefault = true,
};
this.prompt.Clicked += () => {
dirListView.ExecuteSelection ();
canceled = false;
Application.RequestStop ();
};
@@ -430,6 +562,8 @@ namespace Terminal.Gui {
nameEntry.Text = Path.GetFileName(value.ToString());
}
}
public bool Canceled { get => canceled; }
}
/// <summary>

View File

@@ -151,7 +151,8 @@ namespace Terminal.Gui {
Button3Pressed = 8,
Button4Pressed = 16,
RightmostButtonPressed = 2,
WheeledUp = unchecked((int)0x780000),
WheeledDown = unchecked((int)0xFF880000),
}
[Flags]
@@ -595,7 +596,7 @@ namespace Terminal.Gui {
mouseFlag = MouseFlags.Button2Pressed;
break;
case WindowsConsole.ButtonState.Button3Pressed:
case WindowsConsole.ButtonState.RightmostButtonPressed:
mouseFlag = MouseFlags.Button3Pressed;
break;
}
@@ -610,11 +611,57 @@ namespace Terminal.Gui {
mouseFlag = MouseFlags.Button2Clicked;
break;
case WindowsConsole.ButtonState.Button3Pressed:
case WindowsConsole.ButtonState.RightmostButtonPressed:
mouseFlag = MouseFlags.Button3Clicked;
break;
}
LastMouseButtonPressed = null;
switch (mouseEvent.ControlKeyState) {
case WindowsConsole.ControlKeyState.RightControlPressed:
case WindowsConsole.ControlKeyState.LeftControlPressed:
mouseFlag |= MouseFlags.ButtonCtrl;
break;
case WindowsConsole.ControlKeyState.ShiftPressed:
mouseFlag |= MouseFlags.ButtonShift;
break;
}
} else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.DoubleClick) {
switch (mouseEvent.ButtonState) {
case WindowsConsole.ButtonState.Button1Pressed:
mouseFlag = MouseFlags.Button1DoubleClicked;
break;
case WindowsConsole.ButtonState.Button2Pressed:
mouseFlag = MouseFlags.Button2DoubleClicked;
break;
case WindowsConsole.ButtonState.RightmostButtonPressed:
mouseFlag = MouseFlags.Button3DoubleClicked;
break;
}
} else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseWheeled) {
switch (mouseEvent.ButtonState) {
case WindowsConsole.ButtonState.WheeledUp:
mouseFlag = MouseFlags.WheeledUp;
break;
case WindowsConsole.ButtonState.WheeledDown:
mouseFlag = MouseFlags.WheeledDown;
break;
}
switch (mouseEvent.ControlKeyState) {
case WindowsConsole.ControlKeyState.RightControlPressed:
case WindowsConsole.ControlKeyState.LeftControlPressed:
mouseFlag |= MouseFlags.ButtonCtrl;
break;
case WindowsConsole.ControlKeyState.ShiftPressed:
mouseFlag |= MouseFlags.ButtonShift;
break;
}
} else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) {
mouseFlag = MouseFlags.ReportMousePosition;
}

View File

@@ -336,7 +336,7 @@ namespace Terminal.Gui {
/// </summary>
Button1DoubleClicked = unchecked((int)0x8),
/// <summary>
/// The first mouse button was tripple-clicked.
/// The first mouse button was triple-clicked.
/// </summary>
Button1TripleClicked = unchecked((int)0x10),
/// <summary>
@@ -356,7 +356,7 @@ namespace Terminal.Gui {
/// </summary>
Button2DoubleClicked = unchecked((int)0x200),
/// <summary>
/// The second mouse button was tripple-clicked.
/// The second mouse button was triple-clicked.
/// </summary>
Button2TrippleClicked = unchecked((int)0x400),
/// <summary>
@@ -376,7 +376,7 @@ namespace Terminal.Gui {
/// </summary>
Button3DoubleClicked = unchecked((int)0x8000),
/// <summary>
/// The third mouse button was tripple-clicked.
/// The third mouse button was triple-clicked.
/// </summary>
Button3TripleClicked = unchecked((int)0x10000),
/// <summary>
@@ -396,15 +396,15 @@ namespace Terminal.Gui {
/// </summary>
Button4DoubleClicked = unchecked((int)0x200000),
/// <summary>
/// The fourth button was tripple-clicked.
/// The fourth button was triple-clicked.
/// </summary>
Button4TripleClicked = unchecked((int)0x400000),
/// <summary>
/// The fourth button was pressed.
/// Flag: the shift key was pressed when the mouse button took place.
/// </summary>
ButtonShift = unchecked((int)0x2000000),
/// <summary>
/// Flag: the shift key was pressed when the mouse button took place.
/// Flag: the ctrl key was pressed when the mouse button took place.
/// </summary>
ButtonCtrl = unchecked((int)0x1000000),
/// <summary>
@@ -416,6 +416,14 @@ namespace Terminal.Gui {
/// </summary>
ReportMousePosition = unchecked((int)0x8000000),
/// <summary>
/// Vertical button wheeled up.
/// </summary>
WheeledUp = unchecked((int)0x10000000),
/// <summary>
/// Vertical button wheeled up.
/// </summary>
WheeledDown = unchecked((int)0x20000000),
/// <summary>
/// Mask that captures all the events.
/// </summary>
AllEvents = unchecked((int)0x7ffffff),