@ -22,23 +22,25 @@
# include "dialog.h"
static void back_lines ( int n ) ;
static void print_page ( WINDOW * win , int height , int width ) ;
static void print_line ( WINDOW * win , int row , int width ) ;
static void print_page ( WINDOW * win , int height , int width , update_text_fn
update_text , void * data ) ;
static void print_line ( WINDOW * win , int row , int width ) ;
static char * get_line ( void ) ;
static void print_position ( WINDOW * win ) ;
static int hscroll ;
static int begin_reached , end_reached , page_length ;
static const char * buf ;
static const char * page ;
static char * buf ;
static char * page ;
/*
* refresh window content
*/
static void refresh_text_box ( WINDOW * dialog , WINDOW * box , int boxh , int boxw ,
int cur_y , int cur_x )
int cur_y , int cur_x , update_text_fn update_text ,
void * data )
{
print_page ( box , boxh , boxw ) ;
print_page ( box , boxh , boxw , update_text , data ) ;
print_position ( dialog ) ;
wmove ( dialog , cur_y , cur_x ) ; /* Restore cursor position */
wrefresh ( dialog ) ;
@ -47,14 +49,18 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
/*
* Display text from a file in a dialog box .
*
* keys is a null - terminated array
* update_text ( ) may not add or remove any ' \n ' or ' \0 ' in tbuf
*/
int dialog_textbox ( const char * title , const char * tbuf ,
int initial_height , int initial_width )
int dialog_textbox ( const char * title , char * tbuf , int initial_height ,
int initial_width , int * keys , int * _vscroll , int * _hscroll ,
update_text_fn update_text , void * data )
{
int i , x , y , cur_x , cur_y , key = 0 ;
int height , width , boxh , boxw ;
int passed_end ;
WINDOW * dialog , * box ;
bool done = false ;
begin_reached = 1 ;
end_reached = 0 ;
@ -63,6 +69,15 @@ int dialog_textbox(const char *title, const char *tbuf,
buf = tbuf ;
page = buf ; /* page is pointer to start of page to be displayed */
if ( _vscroll & & * _vscroll ) {
begin_reached = 0 ;
for ( i = 0 ; i < * _vscroll ; i + + )
get_line ( ) ;
}
if ( _hscroll )
hscroll = * _hscroll ;
do_resize :
getmaxyx ( stdscr , height , width ) ;
if ( height < 8 | | width < 8 )
@ -120,9 +135,10 @@ do_resize:
/* Print first page of text */
attr_clear ( box , boxh , boxw , dlg . dialog . atr ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y , cur_x ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y , cur_x , update_text ,
data ) ;
while ( ( key ! = KEY_ESC ) & & ( key ! = ' \n ' ) ) {
while ( ! done ) {
key = wgetch ( dialog ) ;
switch ( key ) {
case ' E ' : /* Exit */
@ -130,16 +146,17 @@ do_resize:
case ' X ' :
case ' x ' :
case ' q ' :
delwin ( box ) ;
delwin ( dialog ) ;
return 0 ;
case ' \n ' :
done = true ;
break ;
case ' g ' : /* First page */
case KEY_HOME :
if ( ! begin_reached ) {
begin_reached = 1 ;
page = buf ;
refresh_text_box ( dialog , box , boxh , boxw ,
cur_y , cur_x ) ;
cur_y , cur_x , update_text ,
data ) ;
}
break ;
case ' G ' : /* Last page */
@ -149,45 +166,18 @@ do_resize:
/* point to last char in buf */
page = buf + strlen ( buf ) ;
back_lines ( boxh ) ;
refresh_text_box ( dialog , box , boxh , boxw ,
cur_y , cur_x ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y ,
cur_x , update_text , data ) ;
break ;
case ' K ' : /* Previous line */
case ' k ' :
case KEY_UP :
if ( ! begin_reached ) {
back_lines ( page_length + 1 ) ;
/* We don't call print_page() here but use
* scrolling to ensure faster screen update .
* However , ' end_reached ' and ' page_length '
* should still be updated , and ' page ' should
* point to start of next page . This is done
* by calling get_line ( ) in the following
* ' for ' loop . */
scrollok ( box , TRUE ) ;
wscrl ( box , - 1 ) ; /* Scroll box region down one line */
scrollok ( box , FALSE ) ;
page_length = 0 ;
passed_end = 0 ;
for ( i = 0 ; i < boxh ; i + + ) {
if ( ! i ) {
/* print first line of page */
print_line ( box , 0 , boxw ) ;
wnoutrefresh ( box ) ;
} else
/* Called to update 'end_reached' and 'page' */
get_line ( ) ;
if ( ! passed_end )
page_length + + ;
if ( end_reached & & ! passed_end )
passed_end = 1 ;
}
if ( begin_reached )
break ;
print_position ( dialog ) ;
wmove ( dialog , cur_y , cur_x ) ; /* Restore cursor position */
wrefresh ( dialog ) ;
}
back_lines ( page_length + 1 ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y ,
cur_x , update_text , data ) ;
break ;
case ' B ' : /* Previous page */
case ' b ' :
@ -196,23 +186,18 @@ do_resize:
if ( begin_reached )
break ;
back_lines ( page_length + boxh ) ;
refresh_text_box ( dialog , box , boxh , boxw ,
cur_y , cur_x ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y ,
cur_x , update_text , data ) ;
break ;
case ' J ' : /* Next line */
case ' j ' :
case KEY_DOWN :
if ( ! end_reached ) {
begin_reached = 0 ;
scrollok ( box , TRUE ) ;
scroll ( box ) ; /* Scroll box region up one line */
scrollok ( box , FALSE ) ;
print_line ( box , boxh - 1 , boxw ) ;
wnoutrefresh ( box ) ;
print_position ( dialog ) ;
wmove ( dialog , cur_y , cur_x ) ; /* Restore cursor position */
wrefresh ( dialog ) ;
}
if ( end_reached )
break ;
back_lines ( page_length - 1 ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y ,
cur_x , update_text , data ) ;
break ;
case KEY_NPAGE : /* Next page */
case ' ' :
@ -221,8 +206,8 @@ do_resize:
break ;
begin_reached = 0 ;
refresh_text_box ( dialog , box , boxh , boxw ,
cur_y , cur_x ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y ,
cur_x , update_text , data ) ;
break ;
case ' 0 ' : /* Beginning of line */
case ' H ' : /* Scroll left */
@ -237,8 +222,8 @@ do_resize:
hscroll - - ;
/* Reprint current page to scroll horizontally */
back_lines ( page_length ) ;
refresh_text_box ( dialog , box , boxh , boxw ,
cur_y , cur_x ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y ,
cur_x , update_text , data ) ;
break ;
case ' L ' : /* Scroll right */
case ' l ' :
@ -248,11 +233,12 @@ do_resize:
hscroll + + ;
/* Reprint current page to scroll horizontally */
back_lines ( page_length ) ;
refresh_text_box ( dialog , box , boxh , boxw ,
cur_y , cur_x ) ;
refresh_text_box ( dialog , box , boxh , boxw , cur_y ,
cur_x , update_text , data ) ;
break ;
case KEY_ESC :
key = on_key_esc ( dialog ) ;
if ( on_key_esc ( dialog ) = = KEY_ESC )
done = true ;
break ;
case KEY_RESIZE :
back_lines ( height ) ;
@ -260,11 +246,31 @@ do_resize:
delwin ( dialog ) ;
on_key_resize ( ) ;
goto do_resize ;
default :
for ( i = 0 ; keys [ i ] ; i + + ) {
if ( key = = keys [ i ] ) {
done = true ;
break ;
}
}
}
}
delwin ( box ) ;
delwin ( dialog ) ;
return key ; /* ESC pressed */
if ( _vscroll ) {
const char * s ;
s = buf ;
* _vscroll = 0 ;
back_lines ( page_length ) ;
while ( s < page & & ( s = strchr ( s , ' \n ' ) ) ) {
( * _vscroll ) + + ;
s + + ;
}
}
if ( _hscroll )
* _hscroll = hscroll ;
return key ;
}
/*
@ -301,12 +307,23 @@ static void back_lines(int n)
}
/*
* Print a new page of text . Called by dialog_textbox ( ) .
* Print a new page of text .
*/
static void print_page ( WINDOW * win , int height , int width )
static void print_page ( WINDOW * win , int height , int width , update_text_fn
update_text , void * data )
{
int i , passed_end = 0 ;
if ( update_text ) {
char * end ;
for ( i = 0 ; i < height ; i + + )
get_line ( ) ;
end = page ;
back_lines ( height ) ;
update_text ( buf , page - buf , end - buf , data ) ;
}
page_length = 0 ;
for ( i = 0 ; i < height ; i + + ) {
print_line ( win , i , width ) ;
@ -319,7 +336,7 @@ static void print_page(WINDOW * win, int height, int width)
}
/*
* Print a new line of text . Called by dialog_textbox ( ) and print_page ( ) .
* Print a new line of text .
*/
static void print_line ( WINDOW * win , int row , int width )
{
@ -357,10 +374,8 @@ static char *get_line(void)
end_reached = 0 ;
while ( * page ! = ' \n ' ) {
if ( * page = = ' \0 ' ) {
if ( ! end_reached ) {
end_reached = 1 ;
break ;
}
end_reached = 1 ;
break ;
} else if ( i < MAX_LEN )
line [ i + + ] = * ( page + + ) ;
else {
@ -373,7 +388,7 @@ static char *get_line(void)
if ( i < = MAX_LEN )
line [ i ] = ' \0 ' ;
if ( ! end_reached )
page + + ; /* move pass '\n' */
page + + ; /* move past '\n' */
return line ;
}