CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Path: gap4r8 / pkg / Browse / doc / chap4.txt
Views: 418346
1
2
4 Browsing Tables in GAP using ncurses –The User Interface
3
4
As stated in SectionΒ 1.1, one aim of the Browse package is to provide tools
5
for the quite usual task to show a two-dimensional array or certain rows and
6
columns of it on a character screen in a formatted way, to navigate in this
7
array via key strokes (and mouse events), and to search for strings, to sort
8
the array by row or column values etc.
9
10
The idea is that one starts with an array of data, the main table.
11
Optionally, labels for each row of the main table are given, which are also
12
arranged in an array (with perhaps several columns), the row labels table;
13
analogously, a column labels table of labels for the columns of the main
14
table may be given. The row labels are shown to the left of the main table,
15
the column labels are shown above the main table. The space above the row
16
labels and to the left of the column labels can be used for a fourth table,
17
the corner table, with information about the labels or about the main table.
18
Optionally, a header and a footer may be shown above and below these four
19
tables, respectively. Header and footer are not separated into columns. So
20
the shown window has the following structure.
21
22
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
23
β”‚ header β”‚
24
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
25
β”‚ β”‚ β”‚
26
β”‚ corner β”‚ column labels β”‚
27
β”‚ β”‚ β”‚
28
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
29
β”‚ β”‚ β”‚
30
β”‚ β”‚ β”‚
31
β”‚ row β”‚ main β”‚
32
β”‚ labels β”‚ table β”‚
33
β”‚ β”‚ β”‚
34
β”‚ β”‚ β”‚
35
β”‚ β”‚ β”‚
36
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
37
β”‚ footer β”‚
38
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
39
40
If not the whole tables fit into the window then only subranges of rows and
41
columns of the main table are shown, together with the corresponding row and
42
column labels. Also in this case, the row heights and column widths are
43
computed w.r.t. the whole table not w.r.t. the shown rows and columns. This
44
means that the shown row labels are unchanged if the range of shown columns
45
is changed, the shown column labels are unchanged if the range of shown rows
46
is changed, and the whole corner table is always shown.
47
48
The current chapter describes the user interface for standard applications
49
of this kind, i.Β e., those applications for which one just has to collect
50
the data to be shown in a record –which we call a browse table– without need
51
for additional GAP programming.
52
53
SectionΒ 4.1 gives an overview of the features available in standard browse
54
table applications, and SectionΒ 4.2 describes the data structures used in
55
browse tables. Finally, SectionΒ 4.3 introduces the function
56
NCurses.BrowseGeneric (4.3-1), which is the generic function for showing
57
browse table in visual mode.
58
59
For technical details needed to extend these applications and to build other
60
applications, see ChapterΒ 5.
61
62
Examples of browse table applications are shown in ChapterΒ 6.
63
64
65
4.1 Features Supported by the Function NCurses.BrowseGeneric
66
67
Standard applications of the function NCurses.BrowseGeneric (4.3-1) have the
68
following functionality. Other applications may provide only a subset, or
69
add further functionality, see ChaptersΒ 5 andΒ 6.
70
71
Scrolling:
72
The subranges of shown rows and columns of the main table can be
73
modified, such that the focus area is moved to the left, to the right,
74
up, or down; depending on the context, the focus is moved by one
75
character, by one table cell or a part of it, by the window
76
height/width (minus one character or minus one table cell). If mouse
77
events are enabled then cells can be selected also via mouse clicks.
78
79
Selecting:
80
A cell, row, or column of the main table can be selected; then it is
81
shown highlighted on the screen (by default using the attribute
82
NCurses.attrs.STANDOUT, see SectionΒ 2.1-7). The selection can be moved
83
inside the main table to a neighboring cell, row, or column; this
84
causes also scrolling of the main table when the window borders are
85
reached.
86
87
Searching:
88
A search string is entered by the user, and the first matching cell
89
becomes selected; one can search further for the next matching cell.
90
Global search parameters define what matching means (case sensitive or
91
not, search for substrings or complete words) and what the first and
92
the next matching cells are (search in the whole table or just in the
93
selected row or column, search for whole words or prefixes or
94
suffixes, search forwards or backwards).
95
96
Sorting:
97
If a row or column is selected then the main table can be sorted
98
w.r.t. the entries in this row or column. Global sort parameters
99
describe for example whether one wants to sort ascending or
100
descending, or case sensitive or not.
101
102
If a categorized table is sorted by a column then the category rows
103
are removed and the current sorting and filtering by rows is reset
104
before the table is sorted by the given column. If a table is sorted
105
by a column/row that is already sorted by a column/row then this
106
ordering is reset first.
107
108
Sorting can be undone globally, i.Β e., one can return to the unsorted
109
table.
110
111
Sorting and Categorizing:
112
If a column is selected then the main table can be sorted w.r.t. the
113
entries in this column, and additionally these entries are turned into
114
category rows, i.Β e., additional rows are added to the main table,
115
appearing immediately above the table rows with a fixed value in the
116
selected column, and showing this column value. (There should be no
117
danger to mix up this notion of categories with the one introduced
118
inΒ 'Reference: Categories'.) The category rows can be collapsed (that
119
is, the table rows that belong to this category row are not shown) or
120
expanded (that is, the corresponding table rows are shown). Some of
121
the global search parameters affect the category rows, for example,
122
whether the category rows shall involve a counter showing the number
123
of corresponding data rows, or whether a row of the browse table
124
appears under different category rows.
125
126
Sorting and categorizing can be undone globally, i.Β e., one can return
127
to the unsorted table without category rows.
128
129
Filtering:
130
The browse table can be restricted to those rows or columns in which a
131
given search string occurs. (Also entries in collapsed rows can match;
132
they remain collapsed then.) As a consequence, the category rows are
133
restricted to those under which a matching row occurs. (It is
134
irrelevant whether the search string occurs in category rows.)
135
136
If the search string does not occur at all then a message is printed,
137
and the table remains as it was before. If a browse table is
138
restricted then this fact is indicated by the message restricted table
139
in the lower right corner of the window.
140
141
When a column or row is selected then the search is restricted to the
142
entries in this column or row, respectively. Besides using a search,
143
one can also explicitly hide the selected row or column. Filtering in
144
an already restricted table restricts the shown rows or columns
145
further.
146
147
Filtering can be undone globally, i.Β e., one can return to the
148
unrestricted table.
149
150
Help:
151
Depending on the application and on the situation, different sets of
152
user inputs may be available and different meanings of these inputs
153
are possible. An overview of the currently available inputs and their
154
meanings can be opened in each situation, by hitting the ? key.
155
156
Re-entering:
157
When one has called NCurses.BrowseGeneric (4.3-1) with a browse table,
158
and returns from visual mode to the GAP prompt after some navigation
159
steps, calling NCurses.BrowseGeneric again with this table will enter
160
visual mode in the same situation where it was left. For example, the
161
cell in the top-left position will be the same as before, and if a
162
cell was selected before then this cell will be selected now. (One can
163
avoid this behavior using the optional second argument of
164
NCurses.BrowseGeneric.)
165
166
Logging:
167
The integers corresponding to the user inputs in visual mode are
168
collected in a list that is stored in the component dynamic.log of the
169
browse table. It can be used for repeating the inputs with the replay
170
feature. (For browse table applications that give the user no access
171
to the browse table itself, one can force the log to be assigned to
172
the component log of the global variable BrowseData, see
173
SectionΒ 5.4-1.)
174
175
Replay:
176
Instead of interactively hitting keys in visual mode, one can
177
prescribe the user inputs to a browse table via a replay record; the
178
inputs are then processed with given time intervals. The easiest way
179
to create a meaningful replay record is via the function
180
BrowseData.SetReplay (5.4-2), with argument the dynamic.log component
181
of the browse table in question that was stored in an interactive
182
session.
183
184
The following features are not available in standard applications. They
185
require additional programming.
186
187
Clicking:
188
One possible action is to click a selected cell, row, or column, by
189
hitting the Enter key. It depends on the application what the effect
190
is. A typical situation is that a corresponding GAP object is added to
191
the list of return values of NCurses.BrowseGeneric (4.3-1). Again it
192
depends on the application what this GAP object is. In order to use
193
this feature, one has to provide a record whose components are GAP
194
functions, see SectionΒ 5.4-1 for details. If mouse events are enabled
195
(see NCurses.UseMouse (2.2-10)) then also mouse clicks can be used as
196
an alternative to hitting the Enter key.
197
198
Return Value:
199
The function NCurses.BrowseGeneric (4.3-1) may have an application
200
dependent return value. A typical situation is that a list of objects
201
corresponding to those cells is returned that were clicked in visual
202
mode. In order to use this feature, one has to assign the desired
203
value to the component dynamic.Return of the browse table.
204
205
206
4.2 Data Structures used by NCurses.BrowseGeneric
207
208
4.2-1 BrowseData.IsBrowseTableCellData
209
210
BrowseData.IsBrowseTableCellData( obj )  function
211
Returns: true if the argument is a list or a record in a supported format.
212
213
A table cell data object describes the input data for the contents of a cell
214
in a browse table. It is represented by either an attribute line
215
(seeΒ NCurses.IsAttributeLine (2.2-3)), for cells of height one, or a list of
216
attribute lines or a record with the components rows, a list of attribute
217
lines, and optionally align, a substring of "bclt", which describes the
218
alignment of the attribute lines in the table cell -- bottom, horizontally
219
centered, left, and top alignment; the default is right and vertically
220
centered alignment. (Note that the height of a table row and the width of a
221
table column can be larger than the height and width of an individual cell.)
222
223
 Example 
224
gap> BrowseData.IsBrowseTableCellData( "abc" );
225
true
226
gap> BrowseData.IsBrowseTableCellData( [ "abc", "def" ] );
227
true
228
gap> BrowseData.IsBrowseTableCellData( rec( rows:= [ "ab", "cd" ],
229
>  align:= "tl" ) );
230
true
231
gap> BrowseData.IsBrowseTableCellData( "" );
232
true
233
gap> BrowseData.IsBrowseTableCellData( [] );
234
true
235

236
237
The empty string is a table cell data object of height one and width zero
238
whereas the empty list (which is not in IsStringRep (Reference:
239
IsStringRep)) is a table cell data object of height zero and width zero.
240
241
4.2-2 BrowseData.BlockEntry
242
243
BrowseData.BlockEntry( tablecelldata, height, width )  function
244
Returns: a list of attribute lines.
245
246
For a table cell data object tablecelldata
247
(seeΒ BrowseData.IsBrowseTableCellData (4.2-1)) and two positive integers
248
height and width, BrowseData.BlockEntry returns a list of height attribute
249
lines of displayed length width each (seeΒ NCurses.WidthAttributeLine
250
(2.2-7)), that represents the formatted version of tablecelldata.
251
252
If the rows of tablecelldata have different numbers of displayed characters
253
then they are filled up to the desired numbers of rows and columns,
254
according to the alignment prescribed by tablecelldata; the default
255
alignment is right and vertically centered.
256
257
 Example 
258
gap> BrowseData.BlockEntry( "abc", 3, 5 );
259
[ " ", " abc", " " ]
260
gap> BrowseData.BlockEntry( rec( rows:= [ "ab", "cd" ],
261
>  align:= "tl" ), 3, 5 );
262
[ "ab ", "cd ", " " ]
263

264
265
4.2-3 BrowseData.IsBrowseTable
266
267
BrowseData.IsBrowseTable( obj )  function
268
Returns: true if the argument record has the required components and is
269
consistent.
270
271
A browse table is a GAP record that can be used as the first argument of the
272
function NCurses.BrowseGeneric (4.3-1).
273
274
The supported components of a browse table are work and dynamic, their
275
values must be records: The components in work describe that part of the
276
data that are not likely to depend on user interactions, such as the table
277
entries and their heights and widths. The components in dynamic describe
278
that part of the data that is intended to change with user interactions,
279
such as the currently shown top-left entry of the table, or the current
280
status w.r.t. sorting. For example, suppose you call NCurses.BrowseGeneric
281
(4.3-1) twice with the same browse table; the second call enters the table
282
in the same status where it was left after the first call if the component
283
dynamic is kept, whereas one has to reset (which usually simply means to
284
unbind) the component dynamic if one wants to start in the same status as
285
before the first call.
286
287
The following components are the most important ones for standard browse
288
applications. All these components belong to the work record. For other
289
supported components (of work as well as of dynamic) and for the meaning of
290
the term mode, see SectionΒ 5.2.
291
292
main
293
is the list of lists of table cell data objects that form the matrix
294
to be shown. There is no default for this component. (It is possible
295
to compute the entries of the main table on demand, see the
296
description of the component Main in SectionΒ 5.4-1. In this situation,
297
the value of the component main can be an empty list.)
298
299
header
300
describes a header that shall be shown above the column labels. The
301
value is either a list of attribute lines (static header) or a
302
function or a record whose component names are names of available
303
modes of the browse table (dynamic header). In the function case, the
304
function must take the browse table as its only argument, and return a
305
list of attribute lines. In the record case, the values of the
306
components must be such functions. It is assumed that the number of
307
these lines depends at most on the mode. The default is an empty list,
308
i.Β e., there is no header.
309
310
footer
311
describes a footer that shall be shown below the table. The value is
312
analogous to that of footer. The default is an empty list, i.Β e.,
313
there is no footer.
314
315
labelsRow
316
is a list of row label rows, each being a list of table cell data
317
objects. These rows are shown to the left of the main table. The
318
default is an empty list, i.Β e., there are no row labels.
319
320
labelsCol
321
is a list of column information rows, each being a list of table cell
322
data objects. These rows are shown between the header and the main
323
table. The default is an empty list, i.Β e., there are no column
324
labels.
325
326
corner
327
is a list of lists of table cell data objects that are printed in the
328
upper left corner, i.Β e., to the left of the column label rows and
329
above the row label columns. The default is an empty list.
330
331
sepRow
332
describes the separators above and below rows of the main table and of
333
the row labels table. The value is either an attribute line or a (not
334
necessarily dense) list of attribute lines. In the former case,
335
repetitions of the attribute line are used as separators below each
336
row and above the first row of the table; in the latter case,
337
repetitions of the entry at the first position (if bound) are used
338
above the first row, and repetitions of the last bound entry before
339
the (i+2)-th position (if there is such an entry at all) are used
340
below the i-th table row. The default is an empty string, which means
341
that there are no row separators.
342
343
sepCol
344
describes the separators in front of and behind columns of the main
345
table and of the column labels table. The format of the value is
346
analogous to that of the component sepRow; the default is the string "
347
" (whitespace of width one).
348
349
sepLabelsCol
350
describes the separators above and below rows of the column labels
351
table and of the corner table, analogously to sepRow. The default is
352
an empty string, which means that there are no column label
353
separators.
354
355
sepLabelsRow
356
describes the separators in front of and behind columns of the row
357
labels table and of the corner table, analogously to sepCol. The
358
default is an empty string.
359
360
We give a few examples of standard applications.
361
362
The first example defines a small browse table by prescribing only the
363
component work.main, so the defaults for row and column labels (no such
364
labels), and for separators are used. The table cells are given by plain
365
strings, so they have height one. Usually this table will fit on the screen.
366
367
 Example 
368
gap> m:= 10;; n:= 5;;
369
gap> xpl1:= rec( work:= rec(
370
>  main:= List( [ 1 .. m ], i -> List( [ 1 .. n ],
371
>  j -> String( [ i, j ] ) ) ) ) );;
372
gap> BrowseData.IsBrowseTable( xpl1 );
373
true
374

375
376
In the second example, also row and column labels appear, and different
377
separators are used. The table cells have height three. Also this table will
378
usually fit on the screen.
379
380
 Example 
381
gap> m:= 6;; n:= 5;;
382
gap> xpl2:= rec( work:= rec(
383
>  main:= List( [ 1 .. m ], i -> List( [ 1 .. n ],
384
>  j -> rec( rows:= List( [ -i*j, i*j*1000+j, i-j ], String ),
385
>  align:= "c" ) ) ),
386
>  labelsRow:= List( [ 1 .. m ], i -> [ String( i ) ] ),
387
>  labelsCol:= [ List( [ 1 .. n ], String ) ],
388
>  sepRow:= "-",
389
>  sepCol:= "|",
390
>  ) );;
391
gap> BrowseData.IsBrowseTable( xpl2 );
392
true
393

394
395
The third example additionally has a static header and a dynamic footer, and
396
the table cells involve attributes. This table will usually not fit on the
397
screen. Note that NCurses.attrs.ColorPairs is available only if the terminal
398
supports colors, which can be checked using NCurses.attrs.has_colors
399
(2.2-1).
400
401
 Example 
402
gap> m:= 30;; n:= 25;;
403
gap> xpl3:= rec( work:= rec(
404
>  header:= [ " Example 3" ],
405
>  labelsRow:= List( [ 1 .. 30 ], i -> [ String( i ) ] ),
406
>  sepLabelsRow:= " % ",
407
>  sepLabelsCol:= "=",
408
>  sepRow:= "*",
409
>  sepCol:= " |",
410
>  footer:= t -> [ Concatenation( "top-left entry is: ",
411
>  String( t.dynamic.topleft{ [ 1, 2] } ) ) ],
412
>  ) );;
413
gap> if NCurses.attrs.has_colors then
414
>  xpl3.work.main:= List( [ 1 .. m ], i -> List( [ 1 .. n ],
415
>  j -> rec( rows:= [ String( -i*j ),
416
>  [ NCurses.attrs.BOLD, true,
417
>  NCurses.attrs.ColorPairs[56+1], true,
418
>  String( i*j*1000+j ),
419
>  NCurses.attrs.NORMAL, true ],
420
>  String( i-j ) ],
421
>  align:= "c" ) ) );
422
>  xpl3.work.labelsCol:= [ List( [ 1 .. 30 ], i -> [
423
>  NCurses.attrs.ColorPairs[ 56+4 ], true,
424
>  String( i ),
425
>  NCurses.attrs.NORMAL, true ] ) ];
426
> else
427
>  xpl3.work.main:= List( [ 1 .. m ], i -> List( [ 1 .. n ],
428
>  j -> rec( rows:= [ String( -i*j ),
429
>  [ NCurses.attrs.BOLD, true,
430
>  String( i*j*1000+j ),
431
>  NCurses.attrs.NORMAL, true ],
432
>  String( i-j ) ],
433
>  align:= "c" ) ) );
434
>  xpl3.work.labelsCol:= [ List( [ 1 .. 30 ], i -> [
435
>  NCurses.attrs.BOLD, true,
436
>  String( i ),
437
>  NCurses.attrs.NORMAL, true ] ) ];
438
> fi;
439
gap> BrowseData.IsBrowseTable( xpl3 );
440
true
441

442
443
The fourth example illustrates that highlighting may not work properly for
444
browse tables containing entries whose attributes are not set with explicit
445
Boolean values, see NCurses.IsAttributeLine (2.2-3). Call
446
NCurses.BrowseGeneric (4.3-1) with the browse table xpl4, and select an
447
entry (or a column or a row): Only the middle row of each selected cell will
448
be highlighted, because only in this row, the color attribute is switched on
449
with an explicit true.
450
451
 Example 
452
gap> xpl4:= rec(
453
>  defc:= NCurses.defaultColors,
454
>  wd:= Maximum( List( ~.defc, Length ) ),
455
>  ca:= NCurses.ColorAttr,
456
>  work:= rec(
457
>  header:= [ "Examples of NCurses.ColorAttr" ],
458
>  main:= List( ~.defc, i -> List( ~.defc,
459
>  j -> [ [ ~.ca( i, j ), String( i, ~.wd ) ], # no true!
460
>  [ ~.ca( i, j ), true, String( "on", ~.wd ) ],
461
>  [ ~.ca( i, j ), String( j, ~.wd ) ] ] ) ), # no true!
462
>  labelsRow:= List( ~.defc, i -> [ String( i ) ] ),
463
>  labelsCol:= [ List( ~.defc, String ) ],
464
>  sepRow:= "-",
465
>  sepCol:= [ " |", "|" ],
466
>  ) );;
467
gap> BrowseData.IsBrowseTable( xpl4 );
468
true
469

470
471
472
4.3 The Function NCurses.BrowseGeneric
473
474
4.3-1 NCurses.BrowseGeneric
475
476
NCurses.BrowseGeneric( t[, arec] )  function
477
Returns: an application dependent value, or nothing.
478
479
NCurses.BrowseGeneric is used to show the browse table t
480
(seeΒ BrowseData.IsBrowseTable (4.2-3)) in a formatted way on a text screen,
481
and allows the user to navigate in this table.
482
483
The optional argument arec, if given, must be a record whose components work
484
and dynamic, if bound, are used to provide defaults for missing values in
485
the corresponding components of t. The default for arec and for the
486
components not provided in arec is BrowseData.defaults, seeΒ BrowseData
487
(5.4-1), the function BrowseData.SetDefaults sets these default values.
488
489
At least the component work.main must be bound in t, with value a list of
490
list of table cell data objects, seeΒ BrowseData.IsBrowseTableCellData
491
(4.2-1).
492
493
When the window or the screen is too small for the browse table, according
494
to its component work.minyx, the table will not be shown in visual mode, and
495
fail is returned. (This holds also if there would be no return value of the
496
call in a large enough screen.) Thus one should check for fail results of
497
programmatic calls of NCurses.BrowseGeneric, and one should better not admit
498
fail as a regular return value.
499
500
Most likely, NCurses.BrowseGeneric will not be called on the command line,
501
but the browse table t will be composed by a suitable function which then
502
calls NCurses.BrowseGeneric, see the examples in ChapterΒ 6.
503
504
505