Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
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
Project: cocalc-sagemath-dev-slelievre
Views: 4183461<Chapter Label="chap:browse-user">2<Heading>Browsing Tables in &GAP; using <C>ncurses</C>3–The User Interface</Heading>45As stated in Section <Ref Sect="sec:intro"/>,6one aim of the &Browse; package is to provide tools for the quite usual task7to show a two-dimensional array or certain rows and columns of it8on a character screen in a formatted way,9to navigate in this array via key strokes (and mouse events), and10to search for strings, to sort the array by row or column values etc.11<P/>12The idea is that one starts with an array of data,13the <E>main table</E><Index>main table of a browse table</Index>.14Optionally, labels for each row of the main table are given,15which are also arranged in an array (with perhaps several columns),16the <E>row labels table</E><Index>row labels of a browse table</Index>;17analogously,18a <E>column labels table</E><Index>column labels of a browse table</Index>19of labels for the columns of the main table may be given.20The row labels are shown to the left of the main table, the column labels are21shown above the main table.22The space above the row labels and to the left of the column labels23can be used for a fourth table,24the <E>corner table</E><Index>corner table of a browse table</Index>,25with information about the labels or about the main table.26Optionally, a <E>header</E><Index>header of a browse table</Index>27and a <E>footer</E><Index>footer of a browse table</Index>28may be shown above and below these four tables, respectively.29Header and footer are not separated into columns.30So the shown window has the following structure.31<P/>32<Alt Only="Text">33<Verb>34┌────────────────────────────────┐35│ header │36├────────┬───────────────────────┤37│ │ │38│ corner │ column labels │39│ │ │40├────────┼───────────────────────┤41│ │ │42│ │ │43│ row │ main │44│ labels │ table │45│ │ │46│ │ │47│ │ │48├────────┴───────────────────────┤49│ footer │50└────────────────────────────────┘51</Verb>52</Alt>53<Alt Only="LaTeX">54<![CDATA[55\begin{center}56\begin{tabular}{|c|c|}57\hline58\multicolumn{2}{|c|}{header} \\59\hline60corner & column labels \\61\hline62& \\63row & main \\64labels & table \\65& \\66\hline67\multicolumn{2}{|c|}{footer} \\68\hline69\end{tabular}70\end{center}71]]>72</Alt>73<Alt Only="HTML">74<![CDATA[75</p>76<table rules="all" border="3">77<thead>78<tr>79<td colspan="2" align="center">header</td>80</tr>81</thead>82<tfoot>83<tr>84<td colspan="2" align="center">footer</td>85</tr>86</tfoot>87<tbody>88<tr>89<td align="center">corner</td>90<td align="center">column labels</td>91</tr>92<tr>93<td align="center">row labels</td>94<td align="center">main table</td>95</tr>96</tbody>97</table><p>98]]>99</Alt>100<P/>101If not the whole tables fit into the window then only subranges of rows102and columns of the main table are shown,103together with the corresponding row and column labels.104Also in this case, the row heights and column widths are computed w.r.t.105the whole table not w.r.t. the shown rows and columns.106This means that the shown row labels are unchanged if the range of shown107columns is changed,108the shown column labels are unchanged if the range of shown rows is changed,109and the whole corner table is always shown.110<P/>111The current chapter describes the user interface for112<E>standard applications</E> of this kind, i. e.,113those applications for which one just has to collect the data to be shown114in a record115–which we call a <E>browse table</E>–116without need for additional &GAP; programming.117<P/>118Section <Ref Sect="sec:features"/> gives an overview of the features119available in standard browse table applications,120and Section <Ref Sect="sec:browsebasicdata"/> describes121the data structures used in browse tables.122Finally, Section <Ref Sect="sec:browsegeneric"/> introduces123the function <Ref Func="NCurses.BrowseGeneric"/>,124which is the generic function for showing browse table in visual mode.125<P/>126For technical details needed to extend these applications127and to build other applications,128see Chapter <Ref Chap="chap:browse-prg"/>.129<P/>130Examples of browse table applications are shown131in Chapter <Ref Chap="ch:appl"/>.132133134<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->135<Section Label="sec:features">136<Heading>Features Supported by the Function <C>NCurses.BrowseGeneric</C>137</Heading>138139Standard applications of the function <Ref Func="NCurses.BrowseGeneric"/>140have the following functionality.141Other applications may provide only a subset, or add further functionality,142see Chapters <Ref Chap="chap:browse-prg"/>143and <Ref Chap="ch:appl"/>.144<P/>145<List>146<Mark>Scrolling:<Index>scrolling in a browse table</Index></Mark>147<Item>148The subranges of shown rows and columns of the main table can be modified,149such that the focus area is moved to the left, to the right, up, or down;150depending on the context, the focus is moved by one character, by one table151cell or a part of it, by the window height/width (minus one character or152minus one table cell).153If mouse events <Index>mouse events</Index>154are enabled then cells can be selected also via mouse clicks.155</Item>156<Mark>Selecting:<Index>selecting entries of a browse table</Index></Mark>157<Item>158A cell, row, or column of the main table can be selected;159then it is shown highlighted on the screen (by default using the attribute160<C>NCurses.attrs.STANDOUT</C>,161see Section <Ref Subsect="ssec:ncursesAttrs"/>).162The selection can be moved inside the main table to a neighboring cell,163row, or column; this causes also scrolling of the main table164when the window borders are reached.165</Item>166<Mark>Searching:<Index>searching in a browse table</Index></Mark>167<Item>168A search string is entered by the user, and the first matching cell169becomes selected; one can search further for the next matching cell.170Global search parameters define what matching means (case sensitive or171not, search for substrings or complete words) and what the first and172the next matching cells are (search in the whole table or just in the173selected row or column, search for whole words or prefixes or suffixes,174search forwards or backwards).175</Item>176<Mark>Sorting:<Index>sorting a browse table</Index></Mark>177<Item>178If a row or column is selected then the main table can be sorted w.r.t.179the entries in this row or column.180Global sort parameters describe for example whether one wants to sort181ascending or descending, or case sensitive or not.182<P/>183If a categorized table is sorted by a column then the category rows184are removed and the current sorting and filtering by rows is reset185before the table is sorted by the given column.186If a table is sorted by a column/row that is already sorted by a column/row187then this ordering is reset first.188<P/>189Sorting can be undone globally, i. e., one can return to the190unsorted table.191</Item>192<Mark>Sorting and Categorizing:<Index>categorizing a browse table</Index></Mark>193<Item>194If a column is selected then the main table can be sorted w.r.t.195the entries in this column,196and additionally these entries are turned into <E>category rows</E>,197i. e.,198additional rows are added to the main table, appearing immediately above199the table rows with a fixed value in the selected column, and showing200this column value.201(There should be no danger to mix up this notion of categories with the one202introduced in <Ref Sect="Categories" BookName="ref"/>.)203The category rows can be <E>collapsed</E>204<Index>collapsed category row</Index>205(that is, the table rows that belong to this category row are not shown)206or <E>expanded</E><Index>expanded category row</Index>207(that is, the corresponding table rows are shown).208Some of the global search parameters affect the category rows,209for example, whether the category rows shall involve a counter showing the210number of corresponding data rows,211or whether a row of the browse table appears under different category rows.212<P/>213<!--214When a table gets sorted and categorized that is already categorized,215the new category rows are created on the outermost category level,216so successively categorizing by several columns yields a category hierarchy.217<P/>218-->219Sorting and categorizing can be undone globally, i. e.,220one can return to the unsorted table without category rows.221</Item>222<Mark>Filtering:<Index>filtering a browse table</Index></Mark>223<Item>224The browse table can be restricted to those rows or columns in which225a given search string occurs.226(Also entries in collapsed rows can match; they remain collapsed then.)227As a consequence, the category rows are restricted to those228under which a matching row occurs.229(It is irrelevant whether the search string occurs in category rows.)230<P/>231If the search string does not occur at all then a message is printed,232and the table remains as it was before.233If a browse table is restricted then this fact is indicated by the message234<Q>restricted table</Q> in the lower right corner of the window.235<P/>236When a column or row is selected then the search is restricted to the237entries in this column or row, respectively.238Besides using a search,239one can also explicitly hide the selected row or column.240Filtering in an already restricted table restricts the shown rows or241columns further.242<P/>243Filtering can be undone globally, i. e., one can return to the244unrestricted table.245</Item>246<Mark>Help:<Index>help window for a browse table</Index></Mark>247<Item>248Depending on the application and on the situation,249different sets of user inputs may be available250and different meanings of these inputs are possible.251An overview of the currently available inputs and their meanings252can be opened in each situation, by hitting the <B>?</B> key.253</Item>254<Mark>Re-entering:</Mark>255<Item>256When one has called <Ref Func="NCurses.BrowseGeneric"/> with a browse table,257and returns from visual mode to the &GAP; prompt after some navigation steps,258calling <C>NCurses.BrowseGeneric</C> again with this table259will enter visual mode in the same situation where it was left.260For example, the cell in the top-left position will be the same as before,261and if a cell was selected before then this cell will be selected now.262(One can avoid this behavior using the optional second argument of263<C>NCurses.BrowseGeneric</C>.)264</Item>265<Mark>Logging:<Index>log of a browse table session</Index></Mark>266<Item>267The integers corresponding to the user inputs in visual mode268are collected in a list that is stored in the component269<C>dynamic.log</C> of the browse table.270It can be used for repeating the inputs with the replay feature.271(For browse table applications that give the user no access to the272browse table itself, one can force the log to be assigned to the component273<C>log</C> of the global variable <C>BrowseData</C>,274<Index>BrowseData.log</Index>275see Section <Ref Subsect="BrowseData"/>.)276</Item>277<Mark>Replay:<Index>replay of a browse table session</Index></Mark>278<Item>279Instead of interactively hitting keys in visual mode, one can prescribe280the user inputs to a browse table via a <Q>replay record</Q>;281the inputs are then processed with given time intervals.282The easiest way to create a meaningful replay record is via the function283<Ref Func="BrowseData.SetReplay"/>, with argument the <C>dynamic.log</C>284component of the browse table in question that was stored in an285interactive session.286</Item>287</List>288<P/>289The following features are not available in standard applications.290They require additional programming.291<P/>292<List>293<Mark>Clicking:<Index>click on an entry of a browse table</Index></Mark>294<Item>295One possible action is to <Q>click</Q> a selected cell, row, or column,296by hitting the <B>Enter</B> key.297It depends on the application what the effect is.298A typical situation is that a corresponding &GAP; object is added to the299list of return values of <Ref Func="NCurses.BrowseGeneric"/>.300Again it depends on the application what this &GAP; object is.301In order to use this feature, one has to provide a record whose components302are &GAP; functions, see Section <Ref Subsect="BrowseData"/>303for details.304If mouse events <Index>mouse events</Index> are enabled305(see <Ref Func="NCurses.UseMouse"/>)306then also mouse clicks can be used as an alternative307to hitting the <B>Enter</B> key.308</Item>309<Mark>Return Value:<Index>return value of a browse table session</Index></Mark>310<Item>311The function <Ref Func="NCurses.BrowseGeneric"/> may have312an application dependent return value.313A typical situation is that a list of objects corresponding to those314cells is returned that were <Q>clicked</Q> in visual mode.315In order to use this feature, one has to assign the desired value to316the component <C>dynamic.Return</C> of the browse table.317</Item>318</List>319320</Section>321322323<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->324<Section Label="sec:browsebasicdata">325<Heading>Data Structures used by <C>NCurses.BrowseGeneric</C></Heading>326327<#Include Label="IsBrowseTableCellData_man">328329<#Include Label="BlockEntry_man">330331<#Include Label="IsBrowseTable_man">332333</Section>334335336<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->337<Section Label="sec:browsegeneric">338<Heading>The Function <C>NCurses.BrowseGeneric</C></Heading>339340<#Include Label="NCurses.BrowseGeneric_man">341342</Section>343344</Chapter>345346347<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->348<Chapter Label="chap:browse-prg">349<Heading>Browsing Tables in &GAP; using <C>ncurses</C>350–The Programming Interface</Heading>351352This chapter describes some aspects of the internals of the browse table353handling.354The relevant objects are355<E>action functions</E> that implement the individual navigation steps356(see Section <Ref Sect="sec:actions"/>),357<E>modes</E> that describe the sets of available navigation steps in given358situations (see Section <Ref Sect="sec:modes"/>),359and <E>browse applications</E> that are given by the combination of several360modes (see Section <Ref Sect="sec:applications"/>).361Most of the related data is stored in the global variable362<Ref Var="BrowseData"/>.363364For more details, one should look directly at the code in the file365<F>lib/browse.gi</F> of the &Browse; package.366367<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->368<Section Label="sec:actions">369<Heading>Navigation Steps in Browse Tables</Heading>370371Navigating in a browse table means that after entering visual mode372by calling <Ref Func="NCurses.BrowseGeneric"/>,373the user hits one or several keys, or uses a mouse button,374and if this input is in a given set of admissible inputs375then a corresponding function is executed with argument the browse table376(plus additional information in the case of mouse events).377The function call then may change components in this table378(recommended: components in its <C>dynamic</C> component),379such that the appearance in the window may be different afterwards,380and also the admissible inputs and their effects may have changed.381382<P/>383384The relation between the admissible inputs and the corresponding functions385is application dependent.386However, it is recommended to associate the same input to the same function387in different situations;388for example,389the <B>?</B> key and the <B>F1</B> key should belong to a function390that shows a help window391(see Section <Ref Subsect="BrowseData.actions.ShowHelp"/>),392the <B>q</B> key and the <B>Esc</B> key should belong to a function393that exits the current mode394(Note that the <B>Esc</B> key may be recognized as input395only after a delay of about a second.),396the <B>Q</B> key should belong to a function that exits the browse397application (see Section <Ref Subsect="BrowseData.actions.QuitMode"/>),398the <B>F2</B> key should belong to a function that saves the current399window contents in a global variable400(see Section <Ref Subsect="BrowseData.actions.SaveWindow"/>),401and402the <B>E</B> key should belong to a function that enters a break loop403(see Section <Ref Subsect="BrowseData.actions.Error"/>).404The <B>Enter</B> and <B>Return</B> keys should belong to a <Q>click</Q>405on a selected table entry, and if a category row is selected then they406should expand/collapse this category.407The <B>M</B> key should toggle enabling and disabling mouse events.408Mouse events on a cell or on a category row of a browse table409should move the selected entry to this position;410it is recommended that no functionality is lost if no mouse events are used,411although the number of steps might be reduced when the mouse is used.412413<P/>414415Each such function is wrapped into a record with the components <C>action</C>416(the function itself) and <C>helplines</C> (a list of attribute lines that417describes what the function does).418<Index>action record of a browse table</Index>419The help lines are used by the help feature of <C>NCurses.BrowseGeneric</C>,420see Section <Ref Subsect="BrowseData.actions.ShowHelp"/>.421422<P/>423424The action functions need not return anything.425Whenever the shown screen shall be recomputed after the function call,426the component <C>dynamic.changed</C> of the browse table must be set to427<K>true</K> by the action functions.428429<P/>430431After entering the first characters of an admissible input432that consists of more characters,433the last line of the window with the browse table shows these characters434behind the prefix <Q>partial input:</Q>.435<Index>partial input in a browse table</Index>436One can delete the last entered character of a partial input via the437<B>Delete</B> and <B>Backspace</B> keys.438It is not possible to make these keys part of an admissible input.439When a partial input is given, only those user inputs have an effect440that extend the partial input to (a prefix of) an admissible input.441For example, asking for help by hitting the <B>?</B> key will in general442not work if a partial input had been entered before.443444</Section>445446<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->447<Section Label="sec:modes">448<Heading>Modes in Browse Tables</Heading>449<Index>mode of a browse table</Index>450451In different situations, different inputs may be admissible for the same452browse table, and different functions may belong to the same input.453For example, the meaning of <Q>moving down</Q> can be different depending on454whether a cell is selected or not.455456<P/>457458The set of admissible user inputs and corresponding functions for a459particular situation is collected in a <E>mode</E> of the browse table.460(There should be no danger to mix up this notion of mode with the461<Q>visual mode</Q> introduced in Section <Ref Sect="sec:intro"/>.)462A mode is represented by a record with the components463<C>name</C>464(a string used to associate the mode with the components of <C>header</C>,465<C>headerLength</C>, <C>footer</C>, <C>footerLength</C>, <C>Click</C>,466and for the help screen),467<C>flag</C>468(a string that describes properties of the mode but that can be equal for469different modes),470<C>actions</C>471(a list of records describing the navigation steps that are admissible472in the mode, see Section <Ref Sect="sec:actions"/>),473and <C>ShowTables</C>474(the function used to eventually print the current window contents,475the default is <C>BrowseData.ShowTables</C>).476<Index>BrowseData.ShowTables</Index>477Due to the requirement that each admissible user input uniquely determines478a corresponding function, no admissible user input can be a prefix of479another admissible input, for the same mode.480481<P/>482483Navigation steps (see Section <Ref Sect="sec:actions"/>) can change484the current mode or keep the mode.485It is recommended that each mode has an action to leave this mode;486also an action to leave the browse table application is advisable.487488<P/>489490In a browse table, all available modes are stored in the component491<C>work.availableModes</C>, whose value is a list of mode records.492The value of the component <C>dynamic.activeModes</C> is a list of493mode records that is used as a stack:494The <E>current mode</E> is the last entry in this list,495changing the current mode is achieved496by unbinding the last entry (so one returns to the mode497from which the current mode had been entered by adding it to the list),498by adding a new mode record (so one can later return to the current mode),499or by replacing the last entry by another mode record.500As soon as the <C>dynamic.activeModes</C> list becomes empty,501the browse table application is left.502(In this situation,503if the browse table had been entered from the &GAP; prompt then504visual mode is left, and one returns to the &GAP; prompt.)505506<P/>507508The following modes are predefined by the &Browse; package.509Each of these modes admits the user inputs510<B>?</B>, <B>F1</B>, <B>q</B>, <B>Esc</B>,511<B>Q</B>, <B>F2</B>, <B>E</B>, and <B>M</B>512that have been mentioned in Section <Ref Sect="sec:actions"/>.513514<List>515<Mark>browse</Mark>516<Item>517This mode admits scrolling of the browse table by a cell or by a screen,518searching for a string, selecting a row, a column, or an entry,519and expanding or collapsing all category rows.520</Item>521<Mark>help</Mark>522<Item>523This mode is entered by calling <C>BrowseData.ShowHelpTable</C>;524it shows a help window concerning the actions available in the mode525from which the <C>help</C> mode was entered.526The <C>help</C> mode admits scrolling in the help table527by a cell or by a screen.528See Section <Ref Subsect="BrowseData.actions.ShowHelp"/>529for details.530</Item>531<Mark>select_entry</Mark>532<Item>533In this mode, one table cell is regarded as selected;534this cell is highlighted using the attribute in the component535<C>work.startSelect</C> as a prefix of each attribute line,536see the remark in Section <Ref Subsect="NCurses.IsAttributeLine"/>.537The mode admits moving the selection by one cell in the four directions,538searching for a string and for further occurrences of this string,539expanding or collapsing the current category row or all category rows,540and executing the <Q>click</Q> function of this mode,541provided that the component <C>work.Click.( "select_entry" )</C>542of the browse table is bound.543</Item>544<Mark>select_row</Mark>545<Item>546This is like the <C>select_entry</C> mode,547except that a whole row of the browse table is highlighted.548Searching is restricted to the selected row, and <Q>click</Q> refers to the549function <C>work.Click.( "select_row" )</C>.550</Item>551<Mark>select_row_and_entry</Mark>552<Item>553This is a combination of the <C>select_entry</C> mode and the554<C>select_row</C> mode.555</Item>556<Mark>select_column</Mark>557<Item>558This is like the <C>select_row</C> mode,559just a column is selected not a row.560</Item>561<Mark>select_column_and_entry</Mark>562<Item>563This is like the <C>select_row_and_entry</C> mode,564just a column is selected not a row.565</Item>566</List>567568</Section>569570<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->571<Section Label="sec:applications">572<Heading>Browse Applications</Heading>573574The data in a browse table together with the set of its available modes and575the stack of active modes forms a browse application.576So the part of or all functionality of the &Browse; package can be available577(<Q>standard application</Q>),578or additional functionality can be provided by extending available modes or579adding new modes.580581<P/>582583When <Ref Func="NCurses.BrowseGeneric"/> has been called584with the browse table <A>t</A>, say, the following loop is executed.585586<Enum>587<Item>588If the list <A>t</A><C>.dynamic.activeModes</C> is empty then exit589the browse table, and if the component <A>t</A><C>.dynamic.Return</C>590is bound then return its value.591Otherwise proceed with step 2.592</Item>593<Item>594If <A>t</A><C>.dynamic.changed</C> is <K>true</K> then595call the <C>ShowTables</C> function of the current mode;596this causes a redraw of the window that shows the browse table.597Then go to step 3.598</Item>599<Item>600Get one character of user input.601If then the current user input string is the name of an action of the602current mode then call the corresponding action function and go to step 1;603if the current user input string is just a prefix of the name of some604actions of the current mode then go to step 3;605if the current user input string is not a prefix of any name of an action606of the current mode then discard the last read character and go to step 3.607</Item>608</Enum>609610When one designs a new application, it may be not obvious whether some611functionality shall be implemented via one mode or via several modes.612As a rule of thumb, introducing a new mode is recommended when one needs613a new set of admissible actions in a given situation,614and also if one wants to allow the user to perform some actions615and then to return to the previous status.616617</Section>618619<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->620<Section Label="sec:browse-avail">621<Heading>Predefined Browse Functionalities</Heading>622623<#Include Label="BrowseData_man">624625<#Include Label="SetReplay_man">626627<#Include Label="AlertWithReplay_man">628629<#Include Label="ShowHelp_man">630631<#Include Label="SaveWindow_man">632633<#Include Label="QuitMode_man">634635<#Include Label="Error_man">636637</Section>638</Chapter>639640641642