Next: Menu Driver, Previous: Menu Library, Up: Menu Library [Contents][Index]
To create menus, you first create items, and then post the menu to the
display. After that, all the processing of user responses is done in
an elegant function menu-driver which is the work horse of any
menu program.
The general flow of control of a menu program looks like this.
new-item. You can specify a name and
description for the items.
new-menu by specifying the items with
which it is to be attached.
menu-post and refresh the screen.
menu-driver.
menu-unpost.
Let’s see a program which prints a simple menu and updates the current selection with up, down arrows.
To use menu library functions, you have to use the module (ncurses
menu).
#!/usr/local/bin/guile
-s
!#
(use-modules (srfi srfi-1)
(ncurses curses)
(ncurses menu))
(define stdscr (initscr))
(cbreak!)
(noecho!)
(keypad! stdscr #t)
(let* (;; Labels for the menu items
(names '("Choice 1" "Choice 2" "Choice 3" "Choice 4" "Exit"))
(descriptions '("Description 1" "Description 2" "Description 3"
"Description 4" ""))
;; Create menu items for each label
(my-items (map (lambda (name desc) (new-item name desc))
names
descriptions))
;; Create the menu
(my-menu (new-menu my-items)))
;; Draw the menu
(move stdscr (- (lines) 2) 0)
(addstr stdscr "Press 'q' to Quit")
(post-menu my-menu)
(refresh stdscr)
;; Process the up and down arrow keys. Break the loop if F1 is
;; pressed. Ignore other keys.
(let loop ((c (getch stdscr)))
(cond
;; Move down the menu when down arrow is pressed and then loop.
((eqv? c KEY_DOWN)
(begin
(menu-driver my-menu REQ_DOWN_ITEM)
(loop (getch stdscr))))
;; Move up the menu when the up arrow is pressed and then loop.
((eqv? c KEY_UP)
(begin
(menu-driver my-menu REQ_UP_ITEM)
(loop (getch stdscr))))
;; When enter is pressed, return the selection and quit.
((or (eqv? c KEY_ENTER)
(eqv? c #\cr)
(eqv? c #\nl))
(begin
(unpost-menu my-menu)
(move stdscr (- (lines) 4) 0)
(addstr stdscr
(format #f "You selected item #~a: ~a"
(item-index (current-item my-menu))
(item-name (current-item my-menu))))
(refresh stdscr)
(sleep 2)))
;; If 'Q' or 'q' is pressed, quit. Otherwise, loop.
((not (or (eqv? c #\Q) (eqv? c #\q)))
(loop (getch stdscr)))))
(endwin))
This program demonstrates the basic concepts involved in creating a
menu using menus library. First we create the items using
new-item and then attach them to the menu with new-menu
function. After posting the menu and refreshing the screen, the main
processing loop starts. It reads user input and takes corresponding
action. The function menu-driver is the main work horse of the
menu system. The second parameter to this function tells what’s to be
done with the menu. According to the parameter, menu-driver
does the corresponding task. The value can be either a menu
navigational request, an ASCII character, or a KEY_MOUSE
special key associated with a mouse event.
The menu_driver accepts following navigational requests.
REQ_LEFT_ITEMMove left to an item.
REQ_RIGHT_ITEMMove right to an item.
REQ_UP_ITEMMove up to an item.
REQ_DOWN_ITEMMove down to an item.
REQ_SCR_ULINEScroll up a line.
REQ_SCR_DLINEScroll down a line.
REQ_SCR_DPAGEScroll down a page.
REQ_SCR_UPAGEScroll up a page.
REQ_FIRST_ITEMMove to the first item.
REQ_LAST_ITEMMove to the last item.
REQ_NEXT_ITEMMove to the next item.
REQ_PREV_ITEMMove to the previous item.
REQ_TOGGLE_ITEMSelect/deselect an item.
REQ_CLEAR_PATTERNClear the menu pattern buffer.
REQ_BACK_PATTERNDelete the previous character from the pattern buffer.
REQ_NEXT_MATCHMove to the next item matching the pattern match.
REQ_PREV_MATCHMove to the previous item matching the pattern match.
Don’t get overwhelmed by the number of options. We will see them
slowly one after another. The options of interest in this example are
REQ_UP_ITEM and REQ_DOWN_ITEM. These two options when
passed to menu_driver, menu driver updates the current item to one
item up or down respectively.
Next: Menu Driver, Previous: Menu Library, Up: Menu Library [Contents][Index]