forked from PowerShell/ConsoleGuiTools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConsoleGui.cs
150 lines (129 loc) · 5.29 KB
/
ConsoleGui.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OutGridView.Models;
using Terminal.Gui;
namespace OutGridView.Cmdlet
{
internal class ConsoleGui
{
private const string ACCEPT_TEXT = "Are you sure you want to select\nthese items to send down the pipeline?";
private const string CANCEL_TEXT = "Are you sure you want to cancel?\nNothing will be emitted to the pipeline.";
private const string CLOSE_TEXT = "Are you sure you want to close?";
private bool _cancelled;
internal HashSet<int> SelectedIndexes { get; private set; } = new HashSet<int>();
public void Start(ApplicationData applicationData)
{
Application.Init();
var top = Application.Top;
// Since top is static, state would be preserved in a PowerShell process
// so we remove everything from Top as a precaution.
top.RemoveAll();
// Creates the top-level window to show
var win = new Window(applicationData.Title ?? "Out-ConsoleGridView")
{
X = 0,
Y = 1, // Leave one row for the toplevel menu
// By using Dim.Fill(), it will automatically resize without manual intervention
Width = Dim.Fill(),
Height = Dim.Fill()
};
top.Add(win);
// Creates a menubar, the item "New" has a help menu.
var menu = new MenuBar(new MenuBarItem []
{
new MenuBarItem("_Actions (F9)",
applicationData.PassThru
? new MenuItem []
{
new MenuItem("_Accept", "", () => { if (Quit("Accept", ACCEPT_TEXT)) top.Running = false; }),
new MenuItem("_Cancel", "", () =>{ if (Quit("Cancel", CANCEL_TEXT)) _cancelled = true; top.Running = false; })
}
: new MenuItem []
{
new MenuItem("_Close", "", () =>{ if (Quit("Close", CLOSE_TEXT)) top.Running = false; })
})
});
top.Add(menu);
var gridHeaders = applicationData.DataTable.DataColumns.Select((c) => c.Label).ToList();
// We add one as the offset here to line it up with the data.
win.Add(new Label(GetPaddedString(gridHeaders, top.Frame.Width - 3, offset: 1)));
var items = new List<string>();
foreach (DataTableRow dataTableRow in applicationData.DataTable.Data)
{
var valueList = new List<string>();
foreach (var dataTableColumn in applicationData.DataTable.DataColumns)
{
valueList.Add(dataTableRow.Values[dataTableColumn.ToString()].DisplayValue);
}
// If we have PassThru, then we want to make them selectable. If we make them selectable,
// they have a 8 character addition of a checkbox (" [ ]") that we have to factor in.
int offset = applicationData.PassThru ? 8 : 4;
items.Add(GetPaddedString(valueList, top.Frame.Width - 3, offset));
}
var list = new ListView(items)
{
X = 3,
Y = 3,
Width = Dim.Fill(2),
Height = Dim.Fill(2),
AllowsMarking = applicationData.PassThru
};
win.Add(list);
Application.Run();
if (_cancelled)
{
return;
}
for (int i = 0; i < applicationData.DataTable.Data.Count; i++)
{
if(list.Source.IsMarked(i))
{
SelectedIndexes.Add(i);
}
}
}
public void Close()
{
// top.Running = false;
}
private static bool Quit(string title, string text)
{
var n = MessageBox.Query(50, 7, title, text, "Yes", "No");
return n == 0;
}
private static string GetPaddedString(List<string> strings, int maxWidth, int offset = 0)
{
int colWidth = maxWidth / strings.Count;
var builder = new StringBuilder();
foreach (var str in strings)
{
// If the string won't fit in the column, append an ellipsis.
if (str.Length >= colWidth)
{
builder.Append(' ');
for (int i = 0; i < colWidth - 4; i++)
{
builder.Append(str[i]);
}
builder.Append("...");
continue;
}
// For the case were the string is shorter than the column width,
// append spaces to the beginning.
for (int i = 0; i < colWidth - str.Length; i++)
{
builder.Append(' ');
}
builder.Append(str);
}
if (offset > 0)
{
builder.Remove(0, offset);
}
return builder.ToString();
}
}
}