old-www/HOWTO/NCURSES-Programming-HOWTO/keys.html

348 lines
6.1 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>Interfacing with the key board</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE=" NCURSES Programming HOWTO "
HREF="index.html"><LINK
REL="PREVIOUS"
TITLE="Colors"
HREF="color.html"><LINK
REL="NEXT"
TITLE="Interfacing with the mouse "
HREF="mouse.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>NCURSES Programming HOWTO</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="color.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="mouse.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="KEYS"
></A
>11. Interfacing with the key board</H1
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="KEYSBASICS"
></A
>11.1. The Basics</H2
><P
>No GUI is complete without a strong user interface and to interact with the
user, a curses program should be sensitive to key presses or the mouse actions
done by the user. Let's deal with the keys first.</P
><P
>As you have seen in almost all of the above examples, it's very easy to get key
input from the user. A simple way of getting key presses is to use
<TT
CLASS="LITERAL"
>getch()</TT
> function. The cbreak mode should be
enabled to read keys when you are interested in reading individual key hits
rather than complete lines of text (which usually end with a carriage return).
keypad should be enabled to get the Functions keys, arrow keys etc. See the
initialization section for details.</P
><P
><TT
CLASS="LITERAL"
>getch()</TT
> returns an integer corresponding to the
key pressed. If it is a normal character, the integer value will be equivalent
to the character. Otherwise it returns a number which can be matched with the
constants defined in <TT
CLASS="LITERAL"
>curses.h</TT
>. For example if
the user presses F1, the integer returned is 265. This can be checked using the
macro KEY_F() defined in curses.h. This makes reading keys portable and easy to
manage.</P
><P
>For example, if you call getch() like this</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
> int ch;
ch = getch();</PRE
></FONT
></TD
></TR
></TABLE
><P
>getch() will wait for the user to press a key, (unless you specified a timeout)
and when user presses a key, the corresponding integer is returned. Then you can
check the value returned with the constants defined in curses.h to match against
the keys you want.</P
><P
>The following code piece will do that job.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
> if(ch == KEY_LEFT)
printw("Left arrow is pressed\n");</PRE
></FONT
></TD
></TR
></TABLE
><P
>Let's write a small program which creates a menu which can be navigated by up
and down arrows.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="SIMPLEKEYEX"
></A
>11.2. A Simple Key Usage example</H2
><DIV
CLASS="EXAMPLE"
><A
NAME="BSIKE"
></A
><P
><B
>Example 10. A Simple Key Usage example </B
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="PROGRAMLISTING"
><SPAN
CLASS="INLINEMEDIAOBJECT"
>#include &#60;stdio.h&#62;
#include &#60;ncurses.h&#62;
#define WIDTH 30
#define HEIGHT 10
int startx = 0;
int starty = 0;
char *choices[] = {
"Choice 1",
"Choice 2",
"Choice 3",
"Choice 4",
"Exit",
};
int n_choices = sizeof(choices) / sizeof(char *);
void print_menu(WINDOW *menu_win, int highlight);
int main()
{ WINDOW *menu_win;
int highlight = 1;
int choice = 0;
int c;
initscr();
clear();
noecho();
cbreak(); /* Line buffering disabled. pass on everything */
startx = (80 - WIDTH) / 2;
starty = (24 - HEIGHT) / 2;
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
keypad(menu_win, TRUE);
mvprintw(0, 0, "Use arrow keys to go up and down, Press enter to select a choice");
refresh();
print_menu(menu_win, highlight);
while(1)
{ c = wgetch(menu_win);
switch(c)
{ case KEY_UP:
if(highlight == 1)
highlight = n_choices;
else
--highlight;
break;
case KEY_DOWN:
if(highlight == n_choices)
highlight = 1;
else
++highlight;
break;
case 10:
choice = highlight;
break;
default:
mvprintw(24, 0, "Charcter pressed is = %3d Hopefully it can be printed as '%c'", c, c);
refresh();
break;
}
print_menu(menu_win, highlight);
if(choice != 0) /* User did a choice come out of the infinite loop */
break;
}
mvprintw(23, 0, "You chose choice %d with choice string %s\n", choice, choices[choice - 1]);
clrtoeol();
refresh();
endwin();
return 0;
}
void print_menu(WINDOW *menu_win, int highlight)
{
int x, y, i;
x = 2;
y = 2;
box(menu_win, 0, 0);
for(i = 0; i &#60; n_choices; ++i)
{ if(highlight == i + 1) /* High light the present choice */
{ wattron(menu_win, A_REVERSE);
mvwprintw(menu_win, y, x, "%s", choices[i]);
wattroff(menu_win, A_REVERSE);
}
else
mvwprintw(menu_win, y, x, "%s", choices[i]);
++y;
}
wrefresh(menu_win);
}
</SPAN
></PRE
></FONT
></TD
></TR
></TABLE
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="color.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="mouse.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Colors</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Interfacing with the mouse</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>