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

Views: 418346
1
2
<Chapter Label="chap:browse-user">
3
<Heading>Browsing Tables in &GAP; using <C>ncurses</C>
4
&ndash;The User Interface</Heading>
5
6
As stated in Section&nbsp;<Ref Sect="sec:intro"/>,
7
one aim of the &Browse; package is to provide tools for the quite usual task
8
to show a two-dimensional array or certain rows and columns of it
9
on a character screen in a formatted way,
10
to navigate in this array via key strokes (and mouse events), and
11
to search for strings, to sort the array by row or column values etc.
12
<P/>
13
The idea is that one starts with an array of data,
14
the <E>main table</E><Index>main table of a browse table</Index>.
15
Optionally, labels for each row of the main table are given,
16
which are also arranged in an array (with perhaps several columns),
17
the <E>row labels table</E><Index>row labels of a browse table</Index>;
18
analogously,
19
a <E>column labels table</E><Index>column labels of a browse table</Index>
20
of labels for the columns of the main table may be given.
21
The row labels are shown to the left of the main table, the column labels are
22
shown above the main table.
23
The space above the row labels and to the left of the column labels
24
can be used for a fourth table,
25
the <E>corner table</E><Index>corner table of a browse table</Index>,
26
with information about the labels or about the main table.
27
Optionally, a <E>header</E><Index>header of a browse table</Index>
28
and a <E>footer</E><Index>footer of a browse table</Index>
29
may be shown above and below these four tables, respectively.
30
Header and footer are not separated into columns.
31
So the shown window has the following structure.
32
<P/>
33
<Alt Only="Text">
34
<Verb>
35
┌────────────────────────────────┐
36
│ header │
37
├────────┬───────────────────────┤
38
│ │ │
39
│ corner │ column labels │
40
│ │ │
41
├────────┼───────────────────────┤
42
│ │ │
43
│ │ │
44
│ row │ main │
45
│ labels │ table │
46
│ │ │
47
│ │ │
48
│ │ │
49
├────────┴───────────────────────┤
50
│ footer │
51
└────────────────────────────────┘
52
</Verb>
53
</Alt>
54
<Alt Only="LaTeX">
55
<![CDATA[
56
\begin{center}
57
\begin{tabular}{|c|c|}
58
\hline
59
\multicolumn{2}{|c|}{header} \\
60
\hline
61
corner & column labels \\
62
\hline
63
& \\
64
row & main \\
65
labels & table \\
66
& \\
67
\hline
68
\multicolumn{2}{|c|}{footer} \\
69
\hline
70
\end{tabular}
71
\end{center}
72
]]>
73
</Alt>
74
<Alt Only="HTML">
75
<![CDATA[
76
</p>
77
<table rules="all" border="3">
78
<thead>
79
<tr>
80
<td colspan="2" align="center">header</td>
81
</tr>
82
</thead>
83
<tfoot>
84
<tr>
85
<td colspan="2" align="center">footer</td>
86
</tr>
87
</tfoot>
88
<tbody>
89
<tr>
90
<td align="center">corner</td>
91
<td align="center">column labels</td>
92
</tr>
93
<tr>
94
<td align="center">row labels</td>
95
<td align="center">main table</td>
96
</tr>
97
</tbody>
98
</table><p>
99
]]>
100
</Alt>
101
<P/>
102
If not the whole tables fit into the window then only subranges of rows
103
and columns of the main table are shown,
104
together with the corresponding row and column labels.
105
Also in this case, the row heights and column widths are computed w.r.t.
106
the whole table not w.r.t. the shown rows and columns.
107
This means that the shown row labels are unchanged if the range of shown
108
columns is changed,
109
the shown column labels are unchanged if the range of shown rows is changed,
110
and the whole corner table is always shown.
111
<P/>
112
The current chapter describes the user interface for
113
<E>standard applications</E> of this kind, i.&nbsp;e.,
114
those applications for which one just has to collect the data to be shown
115
in a record
116
&ndash;which we call a <E>browse table</E>&ndash;
117
without need for additional &GAP; programming.
118
<P/>
119
Section&nbsp;<Ref Sect="sec:features"/> gives an overview of the features
120
available in standard browse table applications,
121
and Section&nbsp;<Ref Sect="sec:browsebasicdata"/> describes
122
the data structures used in browse tables.
123
Finally, Section&nbsp;<Ref Sect="sec:browsegeneric"/> introduces
124
the function <Ref Func="NCurses.BrowseGeneric"/>,
125
which is the generic function for showing browse table in visual mode.
126
<P/>
127
For technical details needed to extend these applications
128
and to build other applications,
129
see Chapter&nbsp;<Ref Chap="chap:browse-prg"/>.
130
<P/>
131
Examples of browse table applications are shown
132
in Chapter&nbsp;<Ref Chap="ch:appl"/>.
133
134
135
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
136
<Section Label="sec:features">
137
<Heading>Features Supported by the Function <C>NCurses.BrowseGeneric</C>
138
</Heading>
139
140
Standard applications of the function <Ref Func="NCurses.BrowseGeneric"/>
141
have the following functionality.
142
Other applications may provide only a subset, or add further functionality,
143
see Chapters&nbsp;<Ref Chap="chap:browse-prg"/>
144
and&nbsp;<Ref Chap="ch:appl"/>.
145
<P/>
146
<List>
147
<Mark>Scrolling:<Index>scrolling in a browse table</Index></Mark>
148
<Item>
149
The subranges of shown rows and columns of the main table can be modified,
150
such that the focus area is moved to the left, to the right, up, or down;
151
depending on the context, the focus is moved by one character, by one table
152
cell or a part of it, by the window height/width (minus one character or
153
minus one table cell).
154
If mouse events <Index>mouse events</Index>
155
are enabled then cells can be selected also via mouse clicks.
156
</Item>
157
<Mark>Selecting:<Index>selecting entries of a browse table</Index></Mark>
158
<Item>
159
A cell, row, or column of the main table can be selected;
160
then it is shown highlighted on the screen (by default using the attribute
161
<C>NCurses.attrs.STANDOUT</C>,
162
see Section&nbsp;<Ref Subsect="ssec:ncursesAttrs"/>).
163
The selection can be moved inside the main table to a neighboring cell,
164
row, or column; this causes also scrolling of the main table
165
when the window borders are reached.
166
</Item>
167
<Mark>Searching:<Index>searching in a browse table</Index></Mark>
168
<Item>
169
A search string is entered by the user, and the first matching cell
170
becomes selected; one can search further for the next matching cell.
171
Global search parameters define what matching means (case sensitive or
172
not, search for substrings or complete words) and what the first and
173
the next matching cells are (search in the whole table or just in the
174
selected row or column, search for whole words or prefixes or suffixes,
175
search forwards or backwards).
176
</Item>
177
<Mark>Sorting:<Index>sorting a browse table</Index></Mark>
178
<Item>
179
If a row or column is selected then the main table can be sorted w.r.t.
180
the entries in this row or column.
181
Global sort parameters describe for example whether one wants to sort
182
ascending or descending, or case sensitive or not.
183
<P/>
184
If a categorized table is sorted by a column then the category rows
185
are removed and the current sorting and filtering by rows is reset
186
before the table is sorted by the given column.
187
If a table is sorted by a column/row that is already sorted by a column/row
188
then this ordering is reset first.
189
<P/>
190
Sorting can be undone globally, i.&nbsp;e., one can return to the
191
unsorted table.
192
</Item>
193
<Mark>Sorting and Categorizing:<Index>categorizing a browse table</Index></Mark>
194
<Item>
195
If a column is selected then the main table can be sorted w.r.t.
196
the entries in this column,
197
and additionally these entries are turned into <E>category rows</E>,
198
i.&nbsp;e.,
199
additional rows are added to the main table, appearing immediately above
200
the table rows with a fixed value in the selected column, and showing
201
this column value.
202
(There should be no danger to mix up this notion of categories with the one
203
introduced in&nbsp;<Ref Sect="Categories" BookName="ref"/>.)
204
The category rows can be <E>collapsed</E>
205
<Index>collapsed category row</Index>
206
(that is, the table rows that belong to this category row are not shown)
207
or <E>expanded</E><Index>expanded category row</Index>
208
(that is, the corresponding table rows are shown).
209
Some of the global search parameters affect the category rows,
210
for example, whether the category rows shall involve a counter showing the
211
number of corresponding data rows,
212
or whether a row of the browse table appears under different category rows.
213
<P/>
214
<!--
215
When a table gets sorted and categorized that is already categorized,
216
the new category rows are created on the outermost category level,
217
so successively categorizing by several columns yields a category hierarchy.
218
<P/>
219
-->
220
Sorting and categorizing can be undone globally, i.&nbsp;e.,
221
one can return to the unsorted table without category rows.
222
</Item>
223
<Mark>Filtering:<Index>filtering a browse table</Index></Mark>
224
<Item>
225
The browse table can be restricted to those rows or columns in which
226
a given search string occurs.
227
(Also entries in collapsed rows can match; they remain collapsed then.)
228
As a consequence, the category rows are restricted to those
229
under which a matching row occurs.
230
(It is irrelevant whether the search string occurs in category rows.)
231
<P/>
232
If the search string does not occur at all then a message is printed,
233
and the table remains as it was before.
234
If a browse table is restricted then this fact is indicated by the message
235
<Q>restricted table</Q> in the lower right corner of the window.
236
<P/>
237
When a column or row is selected then the search is restricted to the
238
entries in this column or row, respectively.
239
Besides using a search,
240
one can also explicitly hide the selected row or column.
241
Filtering in an already restricted table restricts the shown rows or
242
columns further.
243
<P/>
244
Filtering can be undone globally, i.&nbsp;e., one can return to the
245
unrestricted table.
246
</Item>
247
<Mark>Help:<Index>help window for a browse table</Index></Mark>
248
<Item>
249
Depending on the application and on the situation,
250
different sets of user inputs may be available
251
and different meanings of these inputs are possible.
252
An overview of the currently available inputs and their meanings
253
can be opened in each situation, by hitting the <B>?</B> key.
254
</Item>
255
<Mark>Re-entering:</Mark>
256
<Item>
257
When one has called <Ref Func="NCurses.BrowseGeneric"/> with a browse table,
258
and returns from visual mode to the &GAP; prompt after some navigation steps,
259
calling <C>NCurses.BrowseGeneric</C> again with this table
260
will enter visual mode in the same situation where it was left.
261
For example, the cell in the top-left position will be the same as before,
262
and if a cell was selected before then this cell will be selected now.
263
(One can avoid this behavior using the optional second argument of
264
<C>NCurses.BrowseGeneric</C>.)
265
</Item>
266
<Mark>Logging:<Index>log of a browse table session</Index></Mark>
267
<Item>
268
The integers corresponding to the user inputs in visual mode
269
are collected in a list that is stored in the component
270
<C>dynamic.log</C> of the browse table.
271
It can be used for repeating the inputs with the replay feature.
272
(For browse table applications that give the user no access to the
273
browse table itself, one can force the log to be assigned to the component
274
<C>log</C> of the global variable <C>BrowseData</C>,
275
<Index>BrowseData.log</Index>
276
see Section&nbsp;<Ref Subsect="BrowseData"/>.)
277
</Item>
278
<Mark>Replay:<Index>replay of a browse table session</Index></Mark>
279
<Item>
280
Instead of interactively hitting keys in visual mode, one can prescribe
281
the user inputs to a browse table via a <Q>replay record</Q>;
282
the inputs are then processed with given time intervals.
283
The easiest way to create a meaningful replay record is via the function
284
<Ref Func="BrowseData.SetReplay"/>, with argument the <C>dynamic.log</C>
285
component of the browse table in question that was stored in an
286
interactive session.
287
</Item>
288
</List>
289
<P/>
290
The following features are not available in standard applications.
291
They require additional programming.
292
<P/>
293
<List>
294
<Mark>Clicking:<Index>click on an entry of a browse table</Index></Mark>
295
<Item>
296
One possible action is to <Q>click</Q> a selected cell, row, or column,
297
by hitting the <B>Enter</B> key.
298
It depends on the application what the effect is.
299
A typical situation is that a corresponding &GAP; object is added to the
300
list of return values of <Ref Func="NCurses.BrowseGeneric"/>.
301
Again it depends on the application what this &GAP; object is.
302
In order to use this feature, one has to provide a record whose components
303
are &GAP; functions, see Section&nbsp;<Ref Subsect="BrowseData"/>
304
for details.
305
If mouse events <Index>mouse events</Index> are enabled
306
(see <Ref Func="NCurses.UseMouse"/>)
307
then also mouse clicks can be used as an alternative
308
to hitting the <B>Enter</B> key.
309
</Item>
310
<Mark>Return Value:<Index>return value of a browse table session</Index></Mark>
311
<Item>
312
The function <Ref Func="NCurses.BrowseGeneric"/> may have
313
an application dependent return value.
314
A typical situation is that a list of objects corresponding to those
315
cells is returned that were <Q>clicked</Q> in visual mode.
316
In order to use this feature, one has to assign the desired value to
317
the component <C>dynamic.Return</C> of the browse table.
318
</Item>
319
</List>
320
321
</Section>
322
323
324
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
325
<Section Label="sec:browsebasicdata">
326
<Heading>Data Structures used by <C>NCurses.BrowseGeneric</C></Heading>
327
328
<#Include Label="IsBrowseTableCellData_man">
329
330
<#Include Label="BlockEntry_man">
331
332
<#Include Label="IsBrowseTable_man">
333
334
</Section>
335
336
337
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
338
<Section Label="sec:browsegeneric">
339
<Heading>The Function <C>NCurses.BrowseGeneric</C></Heading>
340
341
<#Include Label="NCurses.BrowseGeneric_man">
342
343
</Section>
344
345
</Chapter>
346
347
348
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
349
<Chapter Label="chap:browse-prg">
350
<Heading>Browsing Tables in &GAP; using <C>ncurses</C>
351
&ndash;The Programming Interface</Heading>
352
353
This chapter describes some aspects of the internals of the browse table
354
handling.
355
The relevant objects are
356
<E>action functions</E> that implement the individual navigation steps
357
(see Section&nbsp;<Ref Sect="sec:actions"/>),
358
<E>modes</E> that describe the sets of available navigation steps in given
359
situations (see Section&nbsp;<Ref Sect="sec:modes"/>),
360
and <E>browse applications</E> that are given by the combination of several
361
modes (see Section&nbsp;<Ref Sect="sec:applications"/>).
362
Most of the related data is stored in the global variable
363
<Ref Var="BrowseData"/>.
364
365
For more details, one should look directly at the code in the file
366
<F>lib/browse.gi</F> of the &Browse; package.
367
368
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
369
<Section Label="sec:actions">
370
<Heading>Navigation Steps in Browse Tables</Heading>
371
372
Navigating in a browse table means that after entering visual mode
373
by calling <Ref Func="NCurses.BrowseGeneric"/>,
374
the user hits one or several keys, or uses a mouse button,
375
and if this input is in a given set of admissible inputs
376
then a corresponding function is executed with argument the browse table
377
(plus additional information in the case of mouse events).
378
The function call then may change components in this table
379
(recommended: components in its <C>dynamic</C> component),
380
such that the appearance in the window may be different afterwards,
381
and also the admissible inputs and their effects may have changed.
382
383
<P/>
384
385
The relation between the admissible inputs and the corresponding functions
386
is application dependent.
387
However, it is recommended to associate the same input to the same function
388
in different situations;
389
for example,
390
the <B>?</B> key and the <B>F1</B> key should belong to a function
391
that shows a help window
392
(see Section <Ref Subsect="BrowseData.actions.ShowHelp"/>),
393
the <B>q</B> key and the <B>Esc</B> key should belong to a function
394
that exits the current mode
395
(Note that the <B>Esc</B> key may be recognized as input
396
only after a delay of about a second.),
397
the <B>Q</B> key should belong to a function that exits the browse
398
application (see Section <Ref Subsect="BrowseData.actions.QuitMode"/>),
399
the <B>F2</B> key should belong to a function that saves the current
400
window contents in a global variable
401
(see Section <Ref Subsect="BrowseData.actions.SaveWindow"/>),
402
and
403
the <B>E</B> key should belong to a function that enters a break loop
404
(see Section&nbsp;<Ref Subsect="BrowseData.actions.Error"/>).
405
The <B>Enter</B> and <B>Return</B> keys should belong to a <Q>click</Q>
406
on a selected table entry, and if a category row is selected then they
407
should expand/collapse this category.
408
The <B>M</B> key should toggle enabling and disabling mouse events.
409
Mouse events on a cell or on a category row of a browse table
410
should move the selected entry to this position;
411
it is recommended that no functionality is lost if no mouse events are used,
412
although the number of steps might be reduced when the mouse is used.
413
414
<P/>
415
416
Each such function is wrapped into a record with the components <C>action</C>
417
(the function itself) and <C>helplines</C> (a list of attribute lines that
418
describes what the function does).
419
<Index>action record of a browse table</Index>
420
The help lines are used by the help feature of <C>NCurses.BrowseGeneric</C>,
421
see Section <Ref Subsect="BrowseData.actions.ShowHelp"/>.
422
423
<P/>
424
425
The action functions need not return anything.
426
Whenever the shown screen shall be recomputed after the function call,
427
the component <C>dynamic.changed</C> of the browse table must be set to
428
<K>true</K> by the action functions.
429
430
<P/>
431
432
After entering the first characters of an admissible input
433
that consists of more characters,
434
the last line of the window with the browse table shows these characters
435
behind the prefix <Q>partial input:</Q>.
436
<Index>partial input in a browse table</Index>
437
One can delete the last entered character of a partial input via the
438
<B>Delete</B> and <B>Backspace</B> keys.
439
It is not possible to make these keys part of an admissible input.
440
When a partial input is given, only those user inputs have an effect
441
that extend the partial input to (a prefix of) an admissible input.
442
For example, asking for help by hitting the <B>?</B> key will in general
443
not work if a partial input had been entered before.
444
445
</Section>
446
447
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
448
<Section Label="sec:modes">
449
<Heading>Modes in Browse Tables</Heading>
450
<Index>mode of a browse table</Index>
451
452
In different situations, different inputs may be admissible for the same
453
browse table, and different functions may belong to the same input.
454
For example, the meaning of <Q>moving down</Q> can be different depending on
455
whether a cell is selected or not.
456
457
<P/>
458
459
The set of admissible user inputs and corresponding functions for a
460
particular situation is collected in a <E>mode</E> of the browse table.
461
(There should be no danger to mix up this notion of mode with the
462
<Q>visual mode</Q> introduced in Section&nbsp;<Ref Sect="sec:intro"/>.)
463
A mode is represented by a record with the components
464
<C>name</C>
465
(a string used to associate the mode with the components of <C>header</C>,
466
<C>headerLength</C>, <C>footer</C>, <C>footerLength</C>, <C>Click</C>,
467
and for the help screen),
468
<C>flag</C>
469
(a string that describes properties of the mode but that can be equal for
470
different modes),
471
<C>actions</C>
472
(a list of records describing the navigation steps that are admissible
473
in the mode, see Section&nbsp;<Ref Sect="sec:actions"/>),
474
and <C>ShowTables</C>
475
(the function used to eventually print the current window contents,
476
the default is <C>BrowseData.ShowTables</C>).
477
<Index>BrowseData.ShowTables</Index>
478
Due to the requirement that each admissible user input uniquely determines
479
a corresponding function, no admissible user input can be a prefix of
480
another admissible input, for the same mode.
481
482
<P/>
483
484
Navigation steps (see Section <Ref Sect="sec:actions"/>) can change
485
the current mode or keep the mode.
486
It is recommended that each mode has an action to leave this mode;
487
also an action to leave the browse table application is advisable.
488
489
<P/>
490
491
In a browse table, all available modes are stored in the component
492
<C>work.availableModes</C>, whose value is a list of mode records.
493
The value of the component <C>dynamic.activeModes</C> is a list of
494
mode records that is used as a stack:
495
The <E>current mode</E> is the last entry in this list,
496
changing the current mode is achieved
497
by unbinding the last entry (so one returns to the mode
498
from which the current mode had been entered by adding it to the list),
499
by adding a new mode record (so one can later return to the current mode),
500
or by replacing the last entry by another mode record.
501
As soon as the <C>dynamic.activeModes</C> list becomes empty,
502
the browse table application is left.
503
(In this situation,
504
if the browse table had been entered from the &GAP; prompt then
505
visual mode is left, and one returns to the &GAP; prompt.)
506
507
<P/>
508
509
The following modes are predefined by the &Browse; package.
510
Each of these modes admits the user inputs
511
<B>?</B>, <B>F1</B>, <B>q</B>, <B>Esc</B>,
512
<B>Q</B>, <B>F2</B>, <B>E</B>, and <B>M</B>
513
that have been mentioned in Section <Ref Sect="sec:actions"/>.
514
515
<List>
516
<Mark>browse</Mark>
517
<Item>
518
This mode admits scrolling of the browse table by a cell or by a screen,
519
searching for a string, selecting a row, a column, or an entry,
520
and expanding or collapsing all category rows.
521
</Item>
522
<Mark>help</Mark>
523
<Item>
524
This mode is entered by calling <C>BrowseData.ShowHelpTable</C>;
525
it shows a help window concerning the actions available in the mode
526
from which the <C>help</C> mode was entered.
527
The <C>help</C> mode admits scrolling in the help table
528
by a cell or by a screen.
529
See Section <Ref Subsect="BrowseData.actions.ShowHelp"/>
530
for details.
531
</Item>
532
<Mark>select_entry</Mark>
533
<Item>
534
In this mode, one table cell is regarded as selected;
535
this cell is highlighted using the attribute in the component
536
<C>work.startSelect</C> as a prefix of each attribute line,
537
see the remark in Section <Ref Subsect="NCurses.IsAttributeLine"/>.
538
The mode admits moving the selection by one cell in the four directions,
539
searching for a string and for further occurrences of this string,
540
expanding or collapsing the current category row or all category rows,
541
and executing the <Q>click</Q> function of this mode,
542
provided that the component <C>work.Click.( "select_entry" )</C>
543
of the browse table is bound.
544
</Item>
545
<Mark>select_row</Mark>
546
<Item>
547
This is like the <C>select_entry</C> mode,
548
except that a whole row of the browse table is highlighted.
549
Searching is restricted to the selected row, and <Q>click</Q> refers to the
550
function <C>work.Click.( "select_row" )</C>.
551
</Item>
552
<Mark>select_row_and_entry</Mark>
553
<Item>
554
This is a combination of the <C>select_entry</C> mode and the
555
<C>select_row</C> mode.
556
</Item>
557
<Mark>select_column</Mark>
558
<Item>
559
This is like the <C>select_row</C> mode,
560
just a column is selected not a row.
561
</Item>
562
<Mark>select_column_and_entry</Mark>
563
<Item>
564
This is like the <C>select_row_and_entry</C> mode,
565
just a column is selected not a row.
566
</Item>
567
</List>
568
569
</Section>
570
571
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
572
<Section Label="sec:applications">
573
<Heading>Browse Applications</Heading>
574
575
The data in a browse table together with the set of its available modes and
576
the stack of active modes forms a browse application.
577
So the part of or all functionality of the &Browse; package can be available
578
(<Q>standard application</Q>),
579
or additional functionality can be provided by extending available modes or
580
adding new modes.
581
582
<P/>
583
584
When <Ref Func="NCurses.BrowseGeneric"/> has been called
585
with the browse table <A>t</A>, say, the following loop is executed.
586
587
<Enum>
588
<Item>
589
If the list <A>t</A><C>.dynamic.activeModes</C> is empty then exit
590
the browse table, and if the component <A>t</A><C>.dynamic.Return</C>
591
is bound then return its value.
592
Otherwise proceed with step 2.
593
</Item>
594
<Item>
595
If <A>t</A><C>.dynamic.changed</C> is <K>true</K> then
596
call the <C>ShowTables</C> function of the current mode;
597
this causes a redraw of the window that shows the browse table.
598
Then go to step 3.
599
</Item>
600
<Item>
601
Get one character of user input.
602
If then the current user input string is the name of an action of the
603
current mode then call the corresponding action function and go to step 1;
604
if the current user input string is just a prefix of the name of some
605
actions of the current mode then go to step 3;
606
if the current user input string is not a prefix of any name of an action
607
of the current mode then discard the last read character and go to step 3.
608
</Item>
609
</Enum>
610
611
When one designs a new application, it may be not obvious whether some
612
functionality shall be implemented via one mode or via several modes.
613
As a rule of thumb, introducing a new mode is recommended when one needs
614
a new set of admissible actions in a given situation,
615
and also if one wants to allow the user to perform some actions
616
and then to return to the previous status.
617
618
</Section>
619
620
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
621
<Section Label="sec:browse-avail">
622
<Heading>Predefined Browse Functionalities</Heading>
623
624
<#Include Label="BrowseData_man">
625
626
<#Include Label="SetReplay_man">
627
628
<#Include Label="AlertWithReplay_man">
629
630
<#Include Label="ShowHelp_man">
631
632
<#Include Label="SaveWindow_man">
633
634
<#Include Label="QuitMode_man">
635
636
<#Include Label="Error_man">
637
638
</Section>
639
</Chapter>
640
641
642