Next: , Previous: , Up: Menu Library   [Contents][Index]

4.14.1 Menu basics

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.

  1. Initialize curses
  2. Create items using new-item. You can specify a name and description for the items.
  3. Create the menu with new-menu by specifying the items with which it is to be attached.
  4. Post the menu with menu-post and refresh the screen.
  5. Process the user requests with a loop and do necessary updates to menu with menu-driver.
  6. Unpost the menu with menu-unpost.
  7. End curses.

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).


(use-modules (srfi srfi-1)
             (ncurses curses)
             (ncurses menu))

(define stdscr (initscr))
(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))
       ;; 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)))

     ;; Move down the menu when down arrow is pressed and then loop.
     ((eqv? c KEY_DOWN)
        (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)
        (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))
        (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)))))


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.


Move left to an item.


Move right to an item.


Move up to an item.


Move down to an item.


Scroll up a line.


Scroll down a line.


Scroll down a page.


Scroll up a page.


Move to the first item.


Move to the last item.


Move to the next item.


Move to the previous item.


Select/deselect an item.


Clear the menu pattern buffer.


Delete the previous character from the pattern buffer.


Move to the next item matching the pattern match.


Move 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: , Previous: , Up: Menu Library   [Contents][Index]