Next: Other functions, Previous: The basics, Up: Windows Tutorial [Contents][Index]
What fun is it if a window is created and we can’t see it? So the fun
part begins by displaying the window. The functions box and
border can be used to draw a border around the window. Let’s
explore these functions in more detail in this example.
This example isn’t meant as a practical example of what windows are good for. It just shows how to make, draw, erase, and destroy them.
#!/usr/bin/guile
!#
(use-modules (ncurses curses))
;; This procedure makes a new window and draws a box
;; around it
(define (create-newwin height width starty startx)
((lambda (win) ; Make a lambda proc that
(box win (acs-vline) (acs-hline)) ; Makes a box,
(refresh win) ; Draws the window
win) ; Returns the window to the caller
(newwin height width starty startx))) ; Create a window and apply it
; to the lambda function
;; This procedure erases the box around a window and then deletes it
(define (destroy-win win)
(let ((s (normal #\sp)))
(border win s s s s s s s s) ; Draw a box of spaces
(refresh win)
(delwin win)))
;; This prodecure deletes a window than then draw a new one someplace
;; else
(define (move-win win height width starty startx)
(destroy-win win)
(create-newwin height width starty startx))
;; Program Begins
(define stdscr (initscr)) ; Start curses
(cbreak!) ; Line buffering disabled
(keypad! stdscr #t) ; Check for function keys
(let* ((height 3)
(width 10)
(starty (round (/ (- (lines) height) 2)))
(startx (round (/ (- (cols) width) 2))))
(addstr stdscr "Press F1 to exit")
(refresh stdscr)
(let loop ((starty starty)
(startx startx)
(my-win (create-newwin height width starty startx))
(ch (getch stdscr)))
(cond
((eqv? ch KEY_LEFT)
(loop starty
(- startx 1)
(move-win my-win height width starty (- startx 1))
(getch stdscr)))
((eqv? ch KEY_RIGHT)
(loop starty
(+ startx 1)
(move-win my-win height width starty (+ startx 1))
(getch stdscr)))
((eqv? ch KEY_UP)
(loop (- starty 1)
startx
(move-win my-win height width (- starty 1) startx)
(getch stdscr)))
((eqv? ch KEY_DOWN)
(loop (+ starty 1)
startx
(move-win my-win height width (+ starty 1) startx)
(getch stdscr)))
((eqv? ch (key-f 1))
#f)
(else
(loop starty startx my-win (getch stdscr)))))
(endwin))
Don’t scream. I know it is a big example. But there are some important things to explain here. This program creates a rectangular window that can be moved with left, right, up, and down arrow keys. It repeatedly creates and destroys windows as a user presses a key. Don’t go beyond the screen limits. Checking for limits is left as an exercise for the reader. Let’s dissect it line by line.
The create-newwin function creates a window with newwin
and draws a box around it with box. For the horizontal lines in
the box, I chose the special drawing character acs-hline. The
vertical lines are the special drawing character acs-vline.
For the corners of the box, the box procedure will use a guess
of the best available corners for the terminal.
Most terminals will have special box drawing characters available.
The procedure acs-hline and acs-vline will return these
special drawing characters. If the terminal you are using does not
have box drawing characters available, acs-hline and
acs-vline will return the hyphen “-” and the vertical bar
“|”.
The procedure destroy-win first erases the window from the
screen by painting a border of blanks and then calling delwin
to deallocate memory related to it. Depending on the key the user
presses, startx and starty are changed, and a new window
is created.
In the destroy-win, as you can see, I used border
instead of box. The reason is this: border draws a
border around the window and the characters given to it as the four
corners and the four lines. To put it clearly, if you called border
as below:
(border win
(normal #\|)
(normal #\|)
(normal #\-)
(normal #\-)
(normal #\+)
(normal #\+)
(normal #\+)
(normal #\+))
it produces something like this
+-----+ | | | | | | +-----+
It wouldn’t have been sufficient to use (box win (normal #\sp)
(normal #\sp)) to erase the box, because the box procedure
still would have drawn the four corners of the box.
Next: Other functions, Previous: The basics, Up: Windows Tutorial [Contents][Index]