348 lines
6.1 KiB
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 <stdio.h>
|
|
#include <ncurses.h>
|
|
|
|
#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 < 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"
|
|
> </TD
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="right"
|
|
VALIGN="top"
|
|
>Interfacing with the mouse</TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></BODY
|
|
></HTML
|
|
> |