1 #Region "Microsoft.VisualBasic::1191aafe24fd3adee16dc6d13a2c7265, Microsoft.VisualBasic.Core\ApplicationServices\Terminal\Utility\ManualPages.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class ManualPages
35     
36     '         Constructor: (+2 OverloadsSub New
37     
38     '         Function: FromFile, ToString
39     
40     '         Sub: (+2 Overloads) Dispose, ShowManual
41     
42     '     Class IndexedManual
43     
44     '         Constructor: (+1 OverloadsSub New
45     
46     '         Function: __sp
47     
48     '         Sub: PrintPrompted, ShowManual
49     
50     
51     ' /********************************************************************************/
52
53 #End Region
54
55 Namespace Terminal.Utility
56
57     Public Class ManualPages : Implements System.IDisposable
58
59         Protected _manualData As List(Of String)
60         Protected p As Integer
61
62         Public Const MANUAL_PAGE_PROMPTED As String = "Press [ENTER] or [DONW_ARROW] to continute the next page, press [Q] or [ESC] to exit manual...."
63
64         Sub New(strManual As String)
65             Me._manualData = Strings.Split(strManual, vbCr).AsList
66         End Sub
67
68         Sub New(strManual As IEnumerable(Of String))
69             _manualData = strManual.AsList
70         End Sub
71
72         Public Overrides Function ToString() As String
73             Return _manualData.FirstOrDefault & "....."
74         End Function
75
76         ''' <summary>
77         ''' 使用回车键或者箭头下显示下一行,字母q或者ESC键退出Manual
78         ''' </summary>
79         ''' <param name="initLines">最开始显示的行数</param>
80         ''' <remarks></remarks>
81         Public Overridable Sub ShowManual(Optional initLines As Integer = 50, Optional printLines As Integer = 10)
82             If initLines >= _manualData.Count - 1 Then
83                 Call Console.WriteLine(String.Join(vbCrLf, _manualData))
84                 Return
85             End If
86
87             Dim s As String = String.Join(vbCrLf, _manualData.Take(initLines).ToArray)
88             Dim PrintPrompted = Sub()
89                                     Call Console.WriteLine(s)
90                                     Call Console.WriteLine(vbCrLf & vbCrLf & MANUAL_PAGE_PROMPTED)
91                                 End Sub
92             Call PrintPrompted()
93
94             p = initLines
95             _manualData = _manualData.Skip(initLines).AsList
96
97             Do While _manualData.Count > 0
98                 Dim c As ConsoleKeyInfo = Console.ReadKey
99
100                 If c.Key = ConsoleKey.Enter OrElse c.Key = ConsoleKey.DownArrow Then
101                     p += printLines
102                     s = String.Join(vbCrLf, _manualData.Take(printLines).ToArray)
103                     _manualData = _manualData.Skip(printLines).AsList
104
105                     Console.CursorTop -= 1
106                     Call Console.WriteLine(New String(" "c, Console.BufferWidth))
107                     Console.CursorTop -= 2
108                     Call PrintPrompted()
109                 ElseIf c.Key = ConsoleKey.Escape OrElse c.Key = ConsoleKey.Q Then
110                     Call Console.WriteLine()
111                     Return
112                 End If
113             Loop
114
115             Console.CursorTop -= 1
116             Call Console.WriteLine(New String(" "c, Console.BufferWidth))
117             Console.CursorTop -= 2
118         End Sub
119
120         ''' <summary>
121         ''' 从文本文件之中加载Manual数据
122         ''' </summary>
123         ''' <returns></returns>
124         ''' <remarks></remarks>
125         Public Shared Function FromFile(path As StringAs ManualPages
126             Return New ManualPages(IO.File.ReadAllLines(path))
127         End Function
128
129 #Region "IDisposable Support"
130         Private disposedValue As Boolean To detect redundant calls
131
132         ' IDisposable
133         Protected Overridable Sub Dispose(disposing As Boolean)
134             If Not Me.disposedValue Then
135                 If disposing Then
136                     ' TODO: dispose managed state (managed objects).
137                 End If
138
139                 ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
140                 ' TODO: set large fields to null.
141             End If
142             Me.disposedValue = True
143         End Sub
144
145         ' TODO: override Finalize() only if Dispose(      disposing As Boolean) above has code to free unmanaged resources.
146         'Protected Overrides Sub Finalize()
147         '    ' Do not change this code.  Put cleanup code in Dispose(      disposing As Boolean) above.
148         '    Dispose(False)
149         '    MyBase.Finalize()
150         'End Sub
151
152         ' This code added by Visual Basic to correctly implement the disposable pattern.
153         Public Sub Dispose() Implements IDisposable.Dispose
154             Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
155             Dispose(True)
156             GC.SuppressFinalize(Me)
157         End Sub
158 #End Region
159     End Class
160
161     ''' <summary>
162     ''' 有显示标题的
163     ''' </summary>
164     Public Class IndexedManual : Inherits ManualPages
165
166         Dim Title As String
167
168         ''' <summary>
169         ''' 与<see cref="ManualPages"></see>所不同的是,本对象之中的这个字符串数组表示的是一页帮助,而不是一行帮助信息
170         ''' </summary>
171         ''' <param name="Pages"></param>
172         ''' <remarks></remarks>
173         Sub New(Pages As IEnumerable(Of String), title$)
174             Call MyBase.New(Pages)
175             Me.Title = title & vbCrLf & vbCrLf & Navigations
176         End Sub
177
178         Const Navigations As String = "Press [HOME] goto first page and [END] goto last page. [PageUp] for previous page."
179
180         ''' <summary>
181         ''' 使用[Enter][Down_arrow][pagedown]翻下一页[Up_arrow][Pageup]翻上一页,[q]或者[esc]结束,[home]第一页[end]最后一页
182         ''' </summary>
183         ''' <param name="initLines">无用的参数</param>
184         ''' <param name="printLines">无用的参数</param>
185         ''' <remarks></remarks>
186         Public Overrides Sub ShowManual(Optional initLines As Integer = 50, Optional printLines As Integer = 10)
187             Dim currentPage As String = _manualData(p)
188             Call PrintPrompted(p, initLines, printLines)
189
190             Do While p < Me._manualData.Count - 1
191
192                 Dim c As ConsoleKeyInfo = Console.ReadKey
193
194                 If c.Key = ConsoleKey.Enter OrElse
195                     c.Key = ConsoleKey.DownArrow OrElse
196                     c.Key = ConsoleKey.PageDown Then
197
198                     p += 1
199                     Call PrintPrompted(p, initLines, printLines)
200
201                 ElseIf c.Key = ConsoleKey.Escape OrElse
202                     c.Key = ConsoleKey.Q Then
203                     Call Console.WriteLine()
204                     Return
205
206                 ElseIf c.Key = ConsoleKey.UpArrow OrElse
207                     c.Key = ConsoleKey.PageUp Then
208                     If p > 0 Then p -= 1
209                     Call PrintPrompted(p, initLines, printLines)
210
211                 ElseIf c.Key = ConsoleKey.Home Then
212                     p = 0
213                     Call PrintPrompted(p, initLines, printLines)
214
215                 ElseIf c.Key = ConsoleKey.End Then
216                     p = _manualData.Count - 1
217                     Call PrintPrompted(p, initLines, printLines)
218                 End If
219             Loop
220         End Sub
221
222         ''' <summary>
223         ''' 
224         ''' </summary>
225         ''' <param name="p">Current page index</param>
226         Private Sub PrintPrompted(p As Integer, initLines As Integer, printLines As Integer)
227             Dim currentPage As String = _manualData(p)
228
229             Call Console.Clear()
230             Call Console.WriteLine(Title)
231             Call Console.WriteLine()
232             Call Console.WriteLine(__sp(p, _manualData.Count))
233             Call Console.WriteLine(vbCrLf)
234
235             Dim buf As String() = Strings.Split(currentPage, vbCrLf)
236             If buf.Length >= 20 Then
237                 Using Man As ManualPages = New ManualPages(buf)
238                     Call Man.ShowManual(initLines, printLines)
239                 End Using
240             Else
241                 Call Console.WriteLine(currentPage)
242             End If
243
244             If p < _manualData.Count - 1 Then
245                 Call Console.WriteLine(vbCrLf & vbCrLf & MANUAL_PAGE_PROMPTED)
246             End If
247         End Sub
248
249         Private Shared Function __sp(p As Integer, n As IntegerAs String
250             Return $"---------------------------------------------------------------------------------------------------{p + 1}/{n}--"
251         End Function
252     End Class
253 End Namespace