©
本文档使用
php.cn手册 发布
[#1] g_a at freemail dot deletethispart dot hu [2006-02-02 06:03:53]
To determine screen width and height without any external (OS specific) commands, I use:
<?php
ncurses_init();
$fullscreen = ncurses_newwin ( 0, 0, 0, 0);
ncurses_getmaxyx($fullscreen,&$a,&$b);
ncurses_end();
echo "Width:$b\nHeight:$a\n";
?>
[#2] krzysztof dot gorzelak at gmail dot com [2005-11-05 02:36:37]
Here is a small example, how to use STDIN to read keys combinations in console.
$stdin = fopen('php://stdin', 'r');
stream_set_timeout($stdin, 1);
while (1) {
$temp="";
while (1) {
if(stream_select($read = array($stdin), $write = NULL, $except = NULL, 0))
$temp .= ord(fgetc($stdin));
else break;
}
// F1 : $temp == 27914949126
// ALT+F1 : $temp = 2727914949126
// ....
usleep("50000");
}
[#3] kermodebear at kermodebear dot org [2004-06-17 00:27:00]
An implementation of a scrolling selection box:
<?php
function ncurses_menu_select( $options, $values, $max_height = 7, $max_width = 20, $y = 2, $x = 2 ) {
// Size inside of borders
$height = $max_height - 2;
$width = $max_width - 2;
// Number of options
$num_options = count( $options );
// Trim all values to fit
foreach( $options as $key => $value ) {
$options[ $key ] = substr( $value, 0, $width );
}
// Create Window
$menu_window = ncurses_newwin( $max_height, $max_width, $y, $x );
ncurses_wborder( $menu_window, 0, 0, 0, 0, 0, 0, 0, 0 );
// Initialize Window
$current = 0; // Currently selected
$position = 1; // Position in list
$topitem = 0; // Top menu item
for ( $a = 0; $a < min( $height, $num_options ); $a++ ) {
if ( $a == $current ) {
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $options[ $a ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
} else {
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $options[ $a ] );
}
}
ncurses_mvwaddstr( $menu_window, 1, 0, '*' );
ncurses_wrefresh( $menu_window );
// Loop until a selection is made
while( ! in_array( $key = ncurses_getch( $menu_window ), array( 13, 10 ) ) ) {
if ( $key == NCURSES_KEY_UP && $current > 0 ) {
$move = -1;
} else if ( $key == NCURSES_KEY_DOWN && $current < $num_options - 1 ) {
$move = 1;
} else {
continue;
}
$current += $move;
$position += $move;
// If we scroll off the window, redraw items.
if ( $position < 1 || $position > $height ) {
if ( $position < 1 ) {
$position = 1;
} else {
$position = $height;
}
$topitem += $move;
for ( $a = 1; $a <= $height; $a++ ) {
ncurses_mvwaddstr( $menu_window, $a, 1, str_repeat( ' ', $width ) );
if ( $a == $position ) {
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, $a, 1, $options[ $topitem + $a - 1 ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
} else {
ncurses_mvwaddstr( $menu_window, $a, 1, $options[ $topitem + $a - 1 ] );
}
}
} else { // Just update changed items
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, $position, 1, $options[ $current ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, $position - $move, 1, $options[ $current - $move ] );
}
// Update 'scroll bar dot'
ncurses_wborder( $menu_window, 0, 0, 0, 0, 0, 0, 0, 0 );
$dot_position = round ( ( $current / $num_options ) * ( $height - 1 ) );
ncurses_mvwaddstr( $menu_window, 1 + $dot_position, 0, '*' );
ncurses_wrefresh( $menu_window );
}
return $values[ $current ];
}
?>
[#4] kermodebear at kermodebear dot org [2004-06-16 22:21:03]
Not calling ncurses_end() can (will) cause issues with terminals. Although registering a shutdown function which includes ncurses_end() may help, sometimes things go awry and you're stuck with a terminal that is acting in strange ways.
This can be fixed! *NIX systems (FreeBSD, Linux, UNIX, et al.) usually support the 'reset' command which resets the terminal settings and allows you to get things back to normal.
[#5] kermodebear at kermodebear dot org [2004-06-16 22:17:00]
Here is a function that takes an associative array, presents a menu in a new window, allows the user to make a choice using up and down arrows and the enter key, and returns the value of the menu item.
Limitations include:
No way of scrolling a long list, either horiontally or vertically;
No arguments for placement on screen, although this is easy to add;
No multiple selection;
Will produce all kinds of errors and warnings if the terminal is smaller than is necessary to create the window.
I'm very new at using the ncurses library; Comments and improvements would be greatly appreciated!
<?php
function ncurses_menu_select( $menu ) {
$keys = array_keys( $menu );
$values = array_values( $menu );
$height = $width = 0;
$height = count( $menu ) + 2;
foreach( $values as $value ) {
$width = max( $width, strlen( $value ) + 2 );
}
$menu_window = ncurses_newwin( $height, $width, 5, 5 );
ncurses_wborder( $menu_window, 0,0, 0,0, 0,0, 0,0 );
$current = 0;
for( $a = 0; $a < count( $values ); $a++ ) {
if ( $a == $current ) {
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $values[ $a ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
} else {
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $values[ $a ] );
}
}
ncurses_wrefresh( $menu_window );
while( ! in_array( $key = ncurses_getch( $menu_window ), array( 13, 10 ) ) ) {
if ( $key == NCURSES_KEY_UP AND $current > 0 ) {
$move = -1;
} else if ( $key == NCURSES_KEY_DOWN and $current < count( $values ) - 1 ) {
$move = 1;
} else {
$move = 0;
}
ncurses_mvwaddstr( $menu_window, 1 + $current, 1, $values[ $current ] );
$current += $move;
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, 1 + $current, 1, $values[ $current ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
ncurses_wrefresh( $menu_window );
}
ncurses_delwin( $menu_window );
return $keys[ $current ];
}
?>
Example Use:
<?php
// Initialie ncurses
$ncurse = ncurses_init();
// A full screen window
$fullscreen = ncurses_newwin ( 0, 0, 0, 0);
// Add a pretty border
ncurses_border(0,0, 0,0, 0,0, 0,0);
// Draw everything so far
ncurses_refresh();
// Set up menu array
$menu_items = array(
'one' => 'Menu Item #1',
'two' => 'Menu Item #2',
'three' => 'Menu Item #3' );
// Display menu and return selection
$selection = ncurses_menu_select( $menu_items );
// Print selection
ncurses_mvaddstr( 1, 1, 'You selected ' . $menu_items[$selection] . ' with the value ' . $selection );
// Draw updates
ncurses_refresh( $fullscreen );
// End
ncurses_end();
?>
[#6] Habib Valanejad [2004-02-24 21:46:30]
What if you want to draw a new window and after removing it, showing the pervious screen again? Unfortunately, there is no such a thing in php/ncurses as there is in original curses library (touchwin if I'm not mistaken - It has been a long time!).
However, you can do this by a simple trick! You can
dump the screen to a temp file and then restore it back
again!
Take a look at this function:
# Function: show_a_win()
# - Displays a small window and writes something in it.
# - waits for a key
# - shows the pervious screen again
function show_a_win()
{
# Dump the current screen into a temp file:
$tmpfile = tempnam("/tmp", "dump.");
# Create a new window.
$newwin = ncurses_newwin(4, 60, 10, 10);
# Write something and then refresh it
ncurses_mvwaddstr($newwin, 1, 1, "This is a test.");
ncurses_wrefresh($newwin);
# Wait for a key
ncurses_wgetch($newwin);
ncurses_delwin($newwin);
ncurses_scr_restore($tmpfile);
unlink($tmpfile);
}
[#7] Habib Valanejad [2003-12-11 14:30:26]
Here is a function which would do the job for missing
ncurses_wclrtoeol() function:
function wclrtoeol($win)
{
# get current position
ncurses_getyx($win, &$crow, &$ccol);
# get maximum row and col for this window:
ncurses_getmaxyx($win, &$max_row, &$max_col);
for ($col = $ccol; $col < $max_col; $col ++){
ncurses_wmove($win, $crow, $col);
ncurses_waddch($win, 32);
}
}
[#8] rainman at darkwired dot org [2003-07-31 16:55:41]
This is not meant as spam to get people to use my client.
I have been working on a PHP4 IRC client with ncurses interface and I think it is a useful example of how ncurses with php could be used.
It is GPL licensed so you can just go and take a loot at it.
It can be found at http://torc.sourceforge.net or http://www.darkwired.org/projects/torc/
I hope this will help out some of you because php ncurses can be quite difficult I experienced :]
For any questions about the code you can ofcourse just mail me.
[#9] Habib Valanejad [2003-06-25 14:50:51]
I had a small problem building php+ncurses support.
ncurses include files were installed in:
ncurses_installed_dir/include/ncurses
This caused problems when building php with ncurse support.
php was looking for include files in:
ncurses_installed_dir/include
However, include files were located in include/ncurses
I had to make symbolic links of files in ncurses directory so php could see them:
# cd ncurses_insalled_directory/include
# ln -s ncurses
$tty = system("tty");
$handle = fopen($tty, "r");
if (!$handle)
exit("cannot open $tty.\\n");
print "Push space key to terminate.\\n";
ncurses_init();
ncurses_raw();
do {
$ch = fread($handle, 1);
printf('[%d] ', ord($ch));
} while ($ch != " " && ord($ch) != 3);
ncurses_noraw();
ncurses_end();
print "\\n";
fclose($handle);
?>