📄 ncurses-intro.doc
字号:
including a name string part and a description string part. To make menus, you create groups of these items and connect them with menu frame objects. The menu can then by posted, that is written to an associated window. Actually, each menu has two associated windows; a containing window in which the programmer can scribble titles or borders, and a subwindow in which the menu items proper are displayed. If this subwindow is too small to display all the items, it will be a scrollable viewport on the collection of items. A menu may also be unposted (that is, undisplayed), and finally freed to make the storage associated with it and its items available for re-use. The general flow of control of a menu program looks like this: 1. Initialize curses. 2. Create the menu items, using new_item(). 3. Create the menu using new_menu(). 4. Post the menu using post_menu(). 5. Refresh the screen. 6. Process user requests via an input loop. 7. Unpost the menu using unpost_menu(). 8. Free the menu, using free_menu(). 9. Free the items using free_item(). 10. Terminate curses.Selecting items Menus may be multi-valued or (the default) single-valued (see the manual page menu_opts(3x) to see how to change the default). Both types always have a current item. From a single-valued menu you can read the selected value simply by looking at the current item. From a multi-valued menu, you get the selected set by looping through the items applying the item_value() predicate function. Your menu-processing code can use the function set_item_value() to flag the items in the select set. Menu items can be made unselectable using set_item_opts() or item_opts_off() with the O_SELECTABLE argument. This is the only option so far defined for menus, but it is good practice to code as though other option bits might be on.Menu Display The menu library calculates a minimum display size for your window, based on the following variables: * The number and maximum length of the menu items * Whether the O_ROWMAJOR option is enabled * Whether display of descriptions is enabled * Whatever menu format may have been set by the programmer * The length of the menu mark string used for highlighting selected items The function set_menu_format() allows you to set the maximum size of the viewport or menu page that will be used to display menu items. You can retrieve any format associated with a menu with menu_format(). The default format is rows=16, columns=1. The actual menu page may be smaller than the format size. This depends on the item number and size and whether O_ROWMAJOR is on. This option (on by default) causes menu items to be displayed in a `raster-scan' pattern, so that if more than one item will fit horizontally the first couple of items are side-by-side in the top row. The alternative is column-major display, which tries to put the first several items in the first column. As mentioned above, a menu format not large enough to allow all items to fit on-screen will result in a menu display that is vertically scrollable. You can scroll it with requests to the menu driver, which will be described in the section on menu input handling. Each menu has a mark string used to visually tag selected items; see the menu_mark(3x) manual page for details. The mark string length also influences the menu page size. The function scale_menu() returns the minimum display size that the menu code computes from all these factors. There are other menu display attributes including a select attribute, an attribute for selectable items, an attribute for unselectable items, and a pad character used to separate item name text from description text. These have reasonable defaults which the library allows you to change (see the menu_attribs(3x) manual page.Menu Windows Each menu has, as mentioned previously, a pair of associated windows. Both these windows are painted when the menu is posted and erased when the menu is unposted. The outer or frame window is not otherwise touched by the menu routines. It exists so the programmer can associate a title, a border, or perhaps help text with the menu and have it properly refreshed or erased at post/unpost time. The inner window or subwindow is where the current menu page is displayed. By default, both windows are stdscr. You can set them with the functions in menu_win(3x). When you call post_menu(), you write the menu to its subwindow. When you call unpost_menu(), you erase the subwindow, However, neither of these actually modifies the screen. To do that, call wrefresh() or some equivalent.Processing Menu Input The main loop of your menu-processing code should call menu_driver() repeatedly. The first argument of this routine is a menu pointer; the second is a menu command code. You should write an input-fetching routine that maps input characters to menu command codes, and pass its output to menu_driver(). The menu command codes are fully documented in menu_driver(3x). The simplest group of command codes is REQ_NEXT_ITEM, REQ_PREV_ITEM, REQ_FIRST_ITEM, REQ_LAST_ITEM, REQ_UP_ITEM, REQ_DOWN_ITEM, REQ_LEFT_ITEM, REQ_RIGHT_ITEM. These change the currently selected item. These requests may cause scrolling of the menu page if it only partially displayed. There are explicit requests for scrolling which also change the current item (because the select location does not change, but the item there does). These are REQ_SCR_DLINE, REQ_SCR_ULINE, REQ_SCR_DPAGE, and REQ_SCR_UPAGE. The REQ_TOGGLE_ITEM selects or deselects the current item. It is for use in multi-valued menus; if you use it with O_ONEVALUE on, you'll get an error return (E_REQUEST_DENIED). Each menu has an associated pattern buffer. The menu_driver() logic tries to accumulate printable ASCII characters passed in in that buffer; when it matches a prefix of an item name, that item (or the next matching item) is selected. If appending a character yields no new match, that character is deleted from the pattern buffer, and menu_driver() returns E_NO_MATCH. Some requests change the pattern buffer directly: REQ_CLEAR_PATTERN, REQ_BACK_PATTERN, REQ_NEXT_MATCH, REQ_PREV_MATCH. The latter two are useful when pattern buffer input matches more than one item in a multi-valued menu. Each successful scroll or item navigation request clears the pattern buffer. It is also possible to set the pattern buffer explicitly with set_menu_pattern(). Finally, menu driver requests above the constant MAX_COMMAND are considered application-specific commands. The menu_driver() code ignores them and returns E_UNKNOWN_COMMAND.Miscellaneous Other Features Various menu options can affect the processing and visual appearance and input processing of menus. See menu_opts(3x) for details. It is possible to change the current item from application code; this is useful if you want to write your own navigation requests. It is also possible to explicitly set the top row of the menu display. See mitem_current(3x). If your application needs to change the menu subwindow cursor for any reason, pos_menu_cursor() will restore it to the correct location for continuing menu driver processing. It is possible to set hooks to be called at menu initialization and wrapup time, and whenever the selected item changes. See menu_hook(3x). Each item, and each menu, has an associated user pointer on which you can hang application data. See mitem_userptr(3x) and menu_userptr(3x). The Forms Library The form library is a curses extension that supports easy programming of on-screen forms for data entry and program control. The form library first appeared in AT&T System V. The version documented here is the form code distributed with ncurses.Compiling With the form Library Your form-using modules must import the form library declarations with #include <form.h> and must be linked explicitly with the forms library using an -lform argument. Note that they must also link the ncurses library with -lncurses. Many linkers are two-pass and will accept either order, but it is still good practice to put -lform first and -lncurses second.Overview of Forms A form is a collection of fields; each field may be either a label (explanatory text) or a data-entry location. Long forms may be segmented into pages; each entry to a new page clears the screen. To make forms, you create groups of fields and connect them with form frame objects; the form library makes this relatively simple. Once defined, a form can be posted, that is written to an associated window. Actually, each form has two associated windows; a containing window in which the programmer can scribble titles or borders, and a subwindow in which the form fields proper are displayed. As the form user fills out the posted form, navigation and editing keys support movement between fields, editing keys support modifying field, and plain text adds to or changes data in a current field. The form library allows you (the forms designer) to bind each navigation and editing key to any keystroke accepted by curses Fields may have validation conditions on them, so that they check input data for type and value. The form library supplies a rich set of pre-defined field types, and makes it relatively easy to define new ones. Once its transaction is completed (or aborted), a form may be unposted (that is, undisplayed), and finally freed to make the storage associated with it and its items available for re-use. The general flow of control of a form program looks like this: 1. Initialize curses. 2. Create the form fields, using new_field(). 3. Create the form using new_form(). 4. Post the form using post_form(). 5. Refresh the screen. 6. Process user requests via an input loop. 7. Unpost the form using unpost_form(). 8. Free the form, using free_form(). 9. Free the fields using free_field(). 10. Terminate curses. Note that this looks much like a menu program; the form library handles tasks which are in many ways similar, and its interface was obviously designed to resemble that of the menu library wherever possible. In forms programs, however, the `process user requests' is somewhat more complicated than for menus. Besides menu-like navigation operations, the menu driver loop has to support field editing and data validation.Creating and Freeing Fields and Forms The basic function for creating fields is new_field():FIELD *new_field(int height, int width, /* new field size */ int top, int left, /* upper left corner */ int offscreen, /* number of offscreen rows */ int nbuf); /* number of working buffers */ Menu items always occupy a single row, but forms fields may have multiple rows. So new_field() requires you to specify a width and height (the first two arguments, which mist both be greater than zero). You must also specify the location of the field's upper left corner on the screen (the third and fourth arguments, which must be zero or greater). Note that these coordinates are relative to the form subwindow, which will coincide with stdscr by default but need not be stdscr if you've done an explicit set_form_win() call. The fifth argument allows you to specify a number of off-screen rows. If this is zero, the entire field will always be displayed. If it is nonzero, the form will be scrollable, with only one screen-full (initially the top part) displayed at any given time. If you make a field dynamic and grow it so it will no longer fit on the screen, the form will become scrollable even if the offscreen argument was initially zero. The forms library allocates one working buffer per field; the size of each buffer is ((height + offscreen)*width + 1, one character for each position in the field plus a NUL terminator. The sixth argument is the number of additional data buffers to allocate for the field; your application can use them for its own purposes.FIELD *dup_field(FIELD *field, /* field to copy */ int top, int left); /* location of new copy */ The function dup_field() duplicates an existing field at a new location. Size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -