-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathlib-tabtoolkit.muf
executable file
·315 lines (278 loc) · 9.88 KB
/
lib-tabtoolkit.muf
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
( TabToolkit.lib -- Library for handling the fun little tab ASCII layouts )
( and other similar GUI-ish elements. )
( =[c]2019 HopeIslandCoder=============================================== )
( LICENSE: PUBLIC DOMAIN )
( )
( FUNCTIONS )
( )
( tt-make-underline [ length -- string ] )
( Makes an underline string "length" long. )
( )
( tt-make-line [ length -- string ] )
( Makes an dash string "length" long. )
( )
( tt-make-space [ length -- string ] )
( Makes an space string "length" long. )
( )
( tt-shave-to-len [ string length -- string' ] )
( Either cuts the string down to length "length" or pads it as needed. )
( )
( tt-tab-init [ title width -- a ] )
( Initializes a "tab window" -- basically makes the header portion. )
( The title is what goes in the tab title, the width is the overall )
( width of the tab box in characters [should be under 75 characters for )
( total compatability]. Returns a dictionary that should be passed into )
( all tab functions. If the title is blank, it will just make a square. )
( )
( tt-tab-addline [ tab message -- d ] )
( This adds a line to the tab window. Note the line will be truncated if )
( it is too long. The line will have 2 characters worth of space both )
( before and after it, so the maximum length is "width-4". )
( )
( tt-tab-addline-wrap [ tab message -- d ] )
( This wraps a line to fit the tab window. It will try to wrap the line )
( as smartly as it can and use as many lines as it needs. )
( )
( tt-tab-flush [ tab -- d ] )
( "flushes" the tab to screen, therefore displaying it. Whatever has )
( been flushed will not be re-displayed if flushed again. )
( )
( tt-tab-finalize [ tab message -- d ] )
( Puts the closing "pane" on the bottom of the tab window. Optionally )
( embeds a message in the pane. )
( )
( tt-tab-final-flush [ tab message -- ] )
( Runs tt-tab-finalize then tt-tab-flush, eating the tab in the process. )
( )
( tt-custom-init [ header prefix suffix inner-width min-height max-height )
( -- tab ] )
( This allows Tab Toolkit to create a custom "user interface". Header )
( should be an array of strings containing the header banner that will be )
( rendered first. Prefix / suffix will be prepended / appeneded to each )
( line. inner-width is the desired width between prefix and suffix. )
( min-height and max-height are used to control the minimum and maximum )
( size of the text area -- either of these can be 0 to disable the limit. )
( )
( tt-custom-final-flush [ tab footer -- ] )
( This finalizes [and consumes] a tab object. 'footer' should be an )
( array of lines to go as a custom footer on the tab object. )
( If you just want to flush, use tt-tab-flush. If you just want to )
( finalize, use array_notify to output your footer yourself. )
: tt-make-underline ( i -- s' ) ( makes an underline i long)
dup not if
pop "" exit
then
""
begin
"_" strcat
swap 1 - dup while
swap
repeat
pop
;
: tt-make-space ( i -- s' ) ( Makes a series of spaces i long )
dup not if
pop "" exit
then
""
begin
" " strcat
swap 1 - dup while
swap
repeat
pop
;
: tt-make-line ( i -- s' ) ( Makes a series of dashes i long )
dup not if
pop "" exit
then
""
begin
"-" strcat
swap 1 - dup while
swap
repeat
pop
;
: tt-shave-to-len[ string length -- s' ] ( Shaves 's' down to len i )
string @ strlen length @ > if
string @ length @ strcut pop exit
then
string @ length @ string @ strlen - tt-make-space strcat
;
: tt-tab-init[ title width -- d ] ( Initializes a standard tab window )
{
"width" width @ 4 -
"prefix" "| "
"suffix" " |"
"min-height" 0
"max-height" 0
title @ strlen if
"counter" 2
0 " _" title @ strlen 1 + tt-make-underline strcat
1 " _/ " title @ strcat " \\" strcat
dup strlen width @ swap - 1 - tt-make-underline strcat
"header-size" 2
else
"counter" 1
0 " " width @ 2 - tt-make-underline strcat
"header-size" 1
then
}dict
;
: at-maximum? ( tab -- b ) ( Are we at maximum window size? )
dup "max-height" [] dup
rot "counter" [] <=
and
;
: tt-tab-addline[ tab message -- d ] ( Adds a line to the tab window )
tab @ "width" [] var! width
tab @ "counter" [] var! counter
( Check max size )
tab @ at-maximum? if
( Can't add another one -- just return the dict )
tab @ exit
then
tab @ "prefix" [] message @ width @ tt-shave-to-len strcat
tab @ "suffix" [] strcat
tab @ counter @ array_insertitem
counter @ 1 + swap "counter" array_setitem
;
: tt-tab-addline-wrap[ tab message -- d ] ( Adds a word-wrapped line to tab )
var line
var cur
tab @ "width" [] var! width
tab @ "counter" [] var! counter
( Message doesn't need wrapping )
message @ strlen width @ <= if
tab @ message @ tt-tab-addline exit
then
tab @ at-maximum? if
tab @ exit ( Nothing to add )
then
"" line !
"" cur !
begin
message @ strlen cur @ strlen or while
cur @ strlen not if
message @ " " split message ! cur !
then
cur @ strlen not if
message @ " " instring if ( Two spaces in a row )
" " cur !
else
message @ cur !
then
then
( Always include 1 more thingie for the space )
line @ strlen cur @ strlen + 1 + width @ > if
line @ strlen if
tab @ line @ tt-tab-addline tab !
then
cur @ strlen width @ > if
cur @ width @ strcut cur ! tab @ swap tt-tab-addline tab !
else
cur @ line ! "" cur !
then
else
line @ strlen if
line @ " " strcat cur @ strcat line ! "" cur !
else
cur @ line ! "" cur !
then
then
repeat
line @ strlen if
tab @ line @ tt-tab-addline tab !
then
tab @
;
: tt-tab-flush[ tab -- d ] ( "flushes" the tab to screen )
tab @ "counter" [] var! counter
( Do we need more lines? )
tab @ "min-height" [] counter @ > if
begin
tab @ "min-height" []
tab @ "counter" []
> while
tab @ "" tt-tab-addline tab !
repeat
tab @ "counter" [] counter !
then
0
begin
dup counter @ < while
dup tab @ swap [] tell
1 +
repeat
pop
0 tab @ "counter" array_insertitem
;
: tt-tab-finalize[ tab message -- d ] ( Puts the closing line on a tab window )
tab @ "width" [] var! width
tab @ "counter" [] var! counter
message @ strlen not if
" " width @ 2 + tt-make-line strcat
else
" -" message @ strcat dup strlen width @ swap -
3 + tt-make-line strcat
then
tab @ counter @ array_insertitem
counter @ 1 + swap "counter" array_setitem
;
: tt-tab-final-flush ( tab message -- ) ( Finalizes and flushes the tab )
tt-tab-finalize tt-tab-flush pop
;
: tt-custom-init[ header prefix suffix innerWidth minHeight maxHeight ]
( Use header as a base array )
header @ array_explode array_make_dict
dup array_count swap "header-size" array_insertitem
dup array_count 1 - swap "counter" array_insertitem
innerWidth @ swap "width" array_insertitem
prefix @ swap "prefix" array_insertitem
suffix @ swap "suffix" array_insertitem
( Add header size to min and max height because otherwise the header
will count against these numbers. )
minHeight @ if
dup "header-size" [] minHeight @ +
else
0
then
swap "min-height" array_insertitem
maxHeight @ if
dup "header-size" [] maxHeight @ +
else
0
then
swap "max-height" array_insertitem
;
: tt-custom-final-flush ( tab footer -- )
( Flush the array )
swap tt-tab-flush pop
( Output the footer as is )
{ me @ }list array_notify
;
public tt-tab-final-flush
public tt-tab-finalize
public tt-tab-flush
public tt-tab-addline-wrap
public tt-tab-addline
public tt-tab-init
public tt-shave-to-len
public tt-make-space
public tt-make-underline
public tt-make-line
public tt-custom-init
public tt-custom-final-flush
$libdef tt-tab-final-flush
$libdef tt-tab-finalize
$libdef tt-tab-flush
$libdef tt-tab-addline-wrap
$libdef tt-tab-addline
$libdef tt-tab-init
$libdef tt-shave-to-len
$libdef tt-make-space
$libdef tt-make-underline
$libdef tt-make-line
$libdef tt-custom-init
$libdef tt-custom-final-flush