blob: f23d1b88ed6051f72442d537f6bb3f0296c6ff7c [file] [log] [blame] [raw]
/***************************************************************************
opt_window.cpp
-------------------
begin : Thu Jan 17 2002
copyright : (C) 2002 by Roland Riegel
email : feedback@roland-riegel.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "opt_window.h"
const int BORDER_LEFT = 1;
const int BORDER_RIGHT = 1;
const int BORDER_TOP = 2;
const int BORDER_BOTTOM = 1;
OptWindow::OptWindow()
: Window()
{
}
OptWindow::~OptWindow()
{
}
void OptWindow::setFieldChangedFunc( void ( *fieldchangedfunc )( FORM * ) )
{
m_fieldchangedfunc = fieldchangedfunc;
if( m_form )
set_field_term( m_form, m_fieldchangedfunc );
}
void OptWindow::createForm( int width, int height )
{
const int value_field_width = ( width - BORDER_LEFT - BORDER_RIGHT ) / 2;
m_fields = new FIELD* [ 2 * m_options.size() + 1 ];
vector<OptionBase *>::const_iterator r = m_options.begin();
int i = 0, line = 0;
while( r != m_options.end() )
{
line %= height - BORDER_TOP - BORDER_BOTTOM;
m_fields[i] = (*r) -> createCursesLabelField( 0, line, width - value_field_width, 1 );
m_fields[ i + 1 ] = (*r) -> createCursesEditField( value_field_width, line, value_field_width, 1 );
if( line == 0 )
set_new_page( m_fields[i], true );
r++; i += 2; line++;
}
m_fields[ 2 * m_options.size() ] = 0;
m_form = new_form( m_fields );
}
void OptWindow::createWindow( int x, int y, int width, int height )
{
m_window = newwin( height, width, y, x );
}
void OptWindow::createSubWindow( int x, int y, int width, int height )
{
if( m_window && m_form )
{
int sub_width = 0, sub_height = 0;
scale_form( m_form, &sub_height, &sub_width );
m_sub_window = derwin( m_window, sub_height, sub_width, BORDER_TOP, BORDER_BOTTOM );
set_form_win( m_form, m_window );
set_form_sub( m_form, m_sub_window );
}
}
void OptWindow::deleteForm()
{
free_form( m_form );
m_form = 0;
for( vector<OptionBase *>::const_iterator r = m_options.begin(); r != m_options.end(); r++ )
{
(*r) -> deleteCursesEditField();
(*r) -> deleteCursesLabelField();
}
delete[] m_fields;
m_fields = 0;
}
void OptWindow::deleteWindow()
{
delwin( m_window );
m_window = 0;
}
void OptWindow::deleteSubWindow()
{
delwin( m_sub_window );
m_sub_window = 0;
}
//create option window and display the current settings
void OptWindow::show( int x, int y, int width, int height )
{
if( m_visible )
hide();
createForm( width, height );
createWindow( x, y, width, height );
createSubWindow( x, y, width, height );
post_form( m_form );
setFieldChangedFunc( m_fieldchangedfunc );
m_visible = true;
}
//this function is called when a form field changes
//it is called by the function m_fieldchangedfunc
//this can not be done in a nicer way as ncurses does not accept pointers to member functions
void OptWindow::fieldChanged( FORM *changedform )
{
for( vector<OptionBase *>::const_iterator r = m_options.begin(); r != m_options.end(); r++ )
{
if( (*r) -> cursesEditField() == current_field( m_form ) )
(*r) -> assignString( field_buffer( (*r) -> cursesEditField(), 0 ) );
}
}
//hide window and destroy it
void OptWindow::hide()
{
unpost_form( m_form );
deleteForm();
deleteSubWindow();
deleteWindow();
m_visible = false;
}
//process key presses
void OptWindow::processKey( int request )
{
if( m_visible )
{
switch( request )
{
case KEY_LEFT:
request = REQ_PREV_CHAR;
break;
case KEY_RIGHT:
request = REQ_NEXT_CHAR;
break;
case KEY_UP:
request = REQ_PREV_FIELD;
break;
case KEY_DOWN:
case '\t':
request = REQ_NEXT_FIELD;
break;
case KEY_DC:
request = REQ_DEL_CHAR;
break;
case KEY_BACKSPACE:
request = REQ_DEL_PREV;
break;
case KEY_PPAGE:
request = REQ_PREV_CHOICE;
break;
case KEY_NPAGE:
request = REQ_NEXT_CHOICE;
break;
case KEY_HOME:
request = REQ_BEG_LINE;
break;
case KEY_END:
request = REQ_END_LINE;
break;
case '+':
request = REQ_NEXT_PAGE;
break;
case '-':
request = REQ_PREV_PAGE;
break;
}
form_driver( m_form, request );
wrefresh( m_sub_window );
}
}
//export the collection of options shown in the window
vector<OptionBase *>& OptWindow::options()
{
return m_options;
}
void OptWindow::refresh()
{
print( "Options:\n", 0, 0 );
for( int x = 0; x < width(); x++ )
print( '=' );
char fText[40] = "";
sprintf( fText, " <-- (-) page %i/%i (+) --> ", page(), countPages() );
print( fText, width() - strlen( fText ) - 1, 1 );
wrefresh( m_window );
wrefresh( m_sub_window );
}
int OptWindow::page()
{
if( ! m_form ) return 0;
return form_page( m_form ) + 1;
}
int OptWindow::countPages()
{
if( ! m_fields ) return 0;
int pages = 0;
int i = 0;
while( m_fields[i] )
{
if( new_page( m_fields[i] ) )
pages++;
i++;
}
return pages;
}