| home | contents | previous | next page | send comment | send link | add bookmark |

dialog.cpp

/*-------------------------------------------------------------------------*
    DIALOG.CPP

    dialog box creation and input module

    by:  Stephen R. Schmitt
 *-------------------------------------------------------------------------*/

#define NDEBUG // define to comment out assert()

#include <assert.h>
#include <conio.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include "dialog.h"
#include "input.h"

// define some box-drawing characters

#define LF_TOP1     218
#define RT_TOP1     191
#define HORZ1       196
#define VERT1       179
#define LF_BOT1     192
#define RT_BOT1     217

#define LF_TOP2     201
#define RT_TOP2     187
#define HORZ2       205
#define VERT2       186
#define LF_BOT2     200
#define RT_BOT2     188

#define DIALOG_BUFFER 2000

extern input Console;

char dialog_buffer[DIALOG_BUFFER];
char Text_buffer[4000];

/*------------------------------------------------------------------------*
 *  "make_text_ctrl" adds a text control to a dialog box.
 *
 *  returns: control number
 */
int dialog::make_text_ctrl( int cx,             // start col in dialog
                            int cy,             // start row in dialog
                            char *text )        // of control
{
    int i;

    i = count;

    assert( i < MAX_CTRLS );
    assert( cy < dy );
    assert( cx < dx );

    ctrl[i].ctrl   = TEXT_CTRL;
    ctrl[i].y      = cy;
    ctrl[i].x      = cx;
    ctrl[i].text   = text;
    ctrl[i].code   = 0;

    count = i + 1;

    return( i );
}

/*------------------------------------------------------------------------*
 *  "make_push_control" adds a push button control to a dialog box.
 *
 *  returns: control number
 */
int dialog::make_push_ctrl( int cx,             // start col in dialog
                            int cy,             // start row in dialog
                            int key,            // alt+key to select
                            int code,           // value to return
                            char *text )        // of control
{
    int i;

    i = count;

    assert( i < MAX_CTRLS );
    assert( cy < dy );
    assert( cx < dx );

    ctrl[i].ctrl   = PUSH_CTRL;
    ctrl[i].y      = cy;
    ctrl[i].x      = cx;
    ctrl[i].key    = key;
    ctrl[i].code   = code;
    ctrl[i].text   = text;

    count = i + 1;

    return( i );
}

/*------------------------------------------------------------------------*
 *  "make_cbox_control" adds a check box control to a dialog box.
 *
 *  returns: control number
 */
int dialog::make_cbox_ctrl( int cx,             // start col in dialog
                            int cy,             // start row in dialog
                            int key,            // alt+key to select
                            int check,          // value to return
                            char *text )        // of control
{
    int i;

    i = count;

    assert( i < MAX_CTRLS );
    assert( cy < dy );
    assert( cx < dx );

    ctrl[i].ctrl   = CBOX_CTRL;
    ctrl[i].y      = cy;
    ctrl[i].x      = cx;
    ctrl[i].key    = key;
    ctrl[i].code   = 0;
    ctrl[i].check  = check;
    ctrl[i].text   = text;

    count = i + 1;

    return( i );
}

/*------------------------------------------------------------------------*
 *  "make_edit_ctrl" adds a text edit control to a dialog box.
 *
 *  returns: control number
 */
int dialog::make_edit_ctrl( int cx,             // start col in dialog
                            int cy,             // start row in dialog
                            int key,            // alt+key to select
                            int code,           // value to return
                            char *text,         // of control
                            char *data,         // to be edited
                            int  len )          // length of data input
{
    int i;

    i = count;

    assert( i < MAX_CTRLS );
    assert( cy < dy );
    assert( cx < dx );

    ctrl[i].ctrl   = EDIT_CTRL;
    ctrl[i].y      = cy;
    ctrl[i].x      = cx;
    ctrl[i].key    = key;
    ctrl[i].code   = code;
    ctrl[i].text   = text;

    ctrl[i].data   = data;
    ctrl[i].len    = len;
    ctrl[i].cur    = 0;
    ctrl[i].insert = 1;

    count = i + 1;

    return( i );
}

/*------------------------------------------------------------------------*
 *  "make_list_ctrl" adds a list box control to a dialog box.
 *
 *  returns: control number
 */
int dialog::make_list_ctrl( int cx,             // start col in dialog
                            int cy,             // start row in dialog
                            int key,            // alt+key to select
                            int code,           // value to return
                            char *text,         // of control
                            char *list,         // list of strings
                            int  wdth,          // width of list
                            int  size )         // items in list
{
    int i;

    i = count;

    assert( i < MAX_CTRLS );
    assert( cy < dy );
    assert( cx < dx );

    ctrl[i].ctrl   = LIST_CTRL;
    ctrl[i].y      = cy;
    ctrl[i].x      = cx;
    ctrl[i].key    = key;
    ctrl[i].code   = code;
    ctrl[i].text   = text;

    ctrl[i].list   = list;
    ctrl[i].wdth   = wdth;
    ctrl[i].size   = size;
    ctrl[i].item   = 0;
    ctrl[i].top    = 0;

    count = i + 1;

    return( i );
}

/*------------------------------------------------------------------------*
 *  "make_dialog" sets up a dialog box.  Controls are added after this.
 *
 *  returns: nothing
 */
void dialog::make_dialog( char *t,              // title of dialog box
                          int cl,               // col of upper left corner
                          int rw,               // row of upper left corner
                          int wd,               // width of dialog box
                          int ht )              // height of dialog box
{
    title  = t;
    x      = cl;
    y      = rw;
    dx     = wd;
    dy     = ht;
    back   = LIGHTGRAY;
    fore   = WHITE;
    count  = 0;
}

/*------------------------------------------------------------------------*
 *  "format_message" formats a text string for screen display.
 *
 *  returns:  length of message
 */
int dialog::format_message( char *ptr,          // display string
                            char *msg,          // text to display
                            int  norm,          // normal text color
                            int  high )         // highlight text color
{
    int text, j = 0;

    while( *msg != 0 )
    {
        if( *msg == '#' )
        {
            text = high;
            msg++;
        }
        else
            text = norm;

        *ptr = *msg;
        ptr++;
        *ptr = text;
        ptr++;

        msg++;
        j++;
    }

    return( j );
}

/*------------------------------------------------------------------------*
 *  "button_message" writes the text of a button control.
 *
 *  returns:  length of message
 */
int dialog::button_message( int i,              // index number of control
                            int norm,           // normal text color
                            int high )          // highlight text color
{
    int j;

    j = format_message( dialog_buffer, ctrl[i].text, norm, high );
    puttext( x + ctrl[i].x,     y + ctrl[i].y,
             x + ctrl[i].x + j, y + ctrl[i].y,
             dialog_buffer );

    return( j );
}

/*------------------------------------------------------------------------*
 *  "button_shadow" turns the button control's shadow on or off.
 *
 *  returns:  nothing
 */
void dialog::button_shadow( int i,              // index number of control
                            int j,              // length of control
                            int on )            // shadow on/off flag
{
    int k, norm;
    char *ptr, lo, hi;

    if( on )
    {
        norm = 16 * back + BLACK;
        lo = LOW_BLOCK;
        hi = HIGH_BLOCK;
    }
    else
    {
        norm = 16 * back + fore;
        lo = ' ';
        hi = ' ';
    }

    ptr = dialog_buffer;
    *ptr = lo;
    ptr++;
    *ptr = norm;
    puttext( x + ctrl[i].x + j, y + ctrl[i].y,
             x + ctrl[i].x + j, y + ctrl[i].y,
             dialog_buffer );

    k = j;
    ptr = dialog_buffer;
    while( k )
    {
        *ptr = hi;
        ptr++;
        *ptr = norm;
        ptr++;
        k--;
    }

    puttext( x + ctrl[i].x + 1, y + ctrl[i].y + 1,
             x + ctrl[i].x + j, y + ctrl[i].y + 1,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "normal_button" displays a normal button control in a dialog box.
 *
 *  returns:  nothing
 */
void dialog::normal_button( int i )             // index number of control
{
    int j;
    int norm, high;

    norm = 16 * GREEN + BLACK;
    high = 16 * GREEN + YELLOW;

    j = button_message( i, norm, high );
    button_shadow( i, j, 1 );
}

/*------------------------------------------------------------------------*
 *  "select_button" changes a normal button control to a selected button.
 *
 *  returns:  nothing
 */
void dialog::select_button( int i )             // index number of control
{
    int j;
    int norm, high;

    norm = 16 * GREEN + WHITE;
    high = 16 * GREEN + YELLOW;

    j = button_message( i, norm, high );
    button_shadow( i, j, 1 );
}

/*------------------------------------------------------------------------*
 *  "pushed_button" displays a pushed in button control in a dialog box.
 *
 *  returns:  nothing
 */
void dialog::pushed_button( int i )             // index number of control
{
    int j;
    int norm, high;

    norm = 16 * GREEN + BLACK;
    high = 16 * GREEN + YELLOW;

    j = button_message( i, norm, high );
    button_shadow( i, j, 0 );
    delay( 400 );
}

/*------------------------------------------------------------------------*
 *  "write_edit_message" writes the edit message of an edit control.
 *
 *  returns:  nothing
 */
void dialog::write_edit_message( int i,         // index number of control
                                 int norm,      // normal text colors
                                 int high )     // highlighted text colors
{
    int j;

    j = format_message( dialog_buffer, ctrl[i].text, norm, high );
    puttext( x + ctrl[i].x,         y + ctrl[i].y,
             x + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "write_edit_box" writes the edit box of an edit control.
 *
 *  returns:  nothing
 */
void dialog::write_edit_box( int i,             // index number of control
                             int text )         // text colors
{
    char *msg;
    char *ptr;
    int j;

    ptr = dialog_buffer;
    msg = ctrl[i].data;
    for( j = 0; j < ctrl[i].len; j++ )
    {
        *ptr = *msg;
        ptr++;
        *ptr = text;
        ptr++;

        if( *msg )
            msg++;
    }

    puttext( x + ctrl[i].x,                   y + ctrl[i].y + 1,
             x + ctrl[i].x + ctrl[i].len - 1, y + ctrl[i].y + 1,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "init_edit" initializes a normal edit control in a dialog box.
 *
 *  returns:  nothing
 */
void dialog::init_edit( int i )                 // index number of control
{
    int norm;

    _setcursortype( _NOCURSOR );

    ctrl[i].cur = 0;
    norm = 16 * BLUE + LIGHTCYAN;
    write_edit_box( i, norm );
}

/*------------------------------------------------------------------------*
 *  "normal_edit" displays a normal edit control in a dialog box.
 *
 *  returns:  nothing
 */
void dialog::normal_edit( int i )               // index number of control
{
    int norm, high;

    _setcursortype( _NOCURSOR );

    norm = 16 * LIGHTGRAY + BLACK;
    high = 16 * LIGHTGRAY + YELLOW;
    write_edit_message( i, norm, high );

    norm = 16 * BLUE + LIGHTCYAN;
    write_edit_box( i, norm );
}

/*------------------------------------------------------------------------*
 *  "select_edit" displays an active edit control in a dialog box and
 *  does input processing.
 *
 *  returns:  nothing
 */
void dialog::select_edit( int i )               // index number of control
{
    int norm, high;

    norm = 16 * LIGHTGRAY + WHITE;
    high = 16 * LIGHTGRAY + YELLOW;
    write_edit_message( i, norm, high );

    norm = 16 * BLUE + WHITE;
    write_edit_box( i, norm );

    gotoxy( x + ctrl[i].x + ctrl[i].cur,
            y + ctrl[i].y + 1 );

    if( ctrl[i].insert == 0 )
        _setcursortype( _SOLIDCURSOR );
    else
        _setcursortype( _NORMALCURSOR );
}

/*------------------------------------------------------------------------*
 *  "update_edit_data" updates the data display in an active edit control.
 *
 *  returns:  nothing
 */
void dialog::update_edit_data( int i,           // index number of control
                               int key )        // keyboard entry
{
    int j, len;
    int space;

    space = 16 * BLUE + WHITE;

    j = ctrl[i].cur;
    len = strlen( ctrl[i].data );

    if( ( ' ' <= key ) && ( key <= '~' ) && ( j < ctrl[i].len - 1 ) )
    {
        if( ctrl[i].insert )
        {
            memmove( &ctrl[i].data[j+1],
                     &ctrl[i].data[j], len - j + 1);
        }
        ctrl[i].data[j] = (char)key;
        j++;
        write_edit_box( i, space );
    }
    else if( key == BACKSPACE && j > 0 )
    {
        strcpy( &ctrl[i].data[j-1], &ctrl[i].data[j] );
        j--;
        write_edit_box( i, space );
    }
    else if( key == INSERT )
    {
        if( ctrl[i].insert == 1 )
        {
            ctrl[i].insert = 0;
            _setcursortype( _SOLIDCURSOR );
        }
        else
        {
            ctrl[i].insert = 1;
            _setcursortype( _NORMALCURSOR );
        }
    }
    else if( key == DELETE )
    {
        strcpy( &ctrl[i].data[j], &ctrl[i].data[j+1] );
        write_edit_box( i, space );
    }
    else if( key == HOME )
        j = 0;
    else if( key == END )
        j = len;
    else if( key == LF_ARROW && j > 0 )
        j--;
    else if( key == RT_ARROW && j < len )
        j++;

    ctrl[i].cur = j;
    gotoxy( x + ctrl[i].x + j, y + ctrl[i].y + 1 );
}

/*------------------------------------------------------------------------*
 *  "write_list_message" writes the list message of a list control.
 *
 *  returns:  nothing
 */
void dialog::write_list_message( int i,         // index number of control
                                 int norm,      // normal text colors
                                 int high )     // highlighted text colors
{
    int j;

    j = format_message( dialog_buffer, ctrl[i].text, norm, high );
    puttext( x + ctrl[i].x,         y + ctrl[i].y,
             x + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "write_list_box" writes the list box of a list control.
 *
 *  returns:  nothing
 */
void dialog::write_list_box( int i,             // index number of control
                             int norm,          // text colors
                             int high )         // selected colors
{
    char *msg;
    char *ptr;
    int j, k, n, w;
    int text;

    w = ctrl[i].wdth;
    n = ctrl[i].top;
    for( k = 0; k < 10; k++ )
    {
        ptr = dialog_buffer;
        msg = &ctrl[i].list[(k+n)*w];

        if( k + n == ctrl[i].item )
            text = high;
        else
            text = norm;

        for( j = 0; j < w; j++ )
        {
            *ptr = *msg;
            ptr++;
            *ptr = text;
            ptr++;
            msg++;
        }

        puttext( x + ctrl[i].x,         y + ctrl[i].y + k + 1,
                 x + ctrl[i].x + w - 1, y + ctrl[i].y + k + 1,
                 dialog_buffer );
    }
}

/*------------------------------------------------------------------------*
 *  "normal_list" displays a normal list control in a dialog box.
 *
 *  returns:  nothing
 */
void dialog::normal_list( int i )               // index number of control
{
    int norm, high;

    _setcursortype( _NOCURSOR );

    norm = 16 * LIGHTGRAY + BLACK;
    high = 16 * LIGHTGRAY + YELLOW;
    write_list_message( i, norm, high );

    norm = 16 * BLUE + LIGHTCYAN;
    high = 16 * BLUE + WHITE;
    write_list_box( i, norm, high );
}

/*------------------------------------------------------------------------*
 *  "select_list" displays an active list control in a dialog box and
 *  does input processing.
 *
 *  returns:  nothing
 */
void dialog::select_list( int i )               // index number of control
{
    int norm, high;

    norm = 16 * LIGHTGRAY + WHITE;
    high = 16 * LIGHTGRAY + YELLOW;
    write_list_message( i, norm, high );

    norm = 16 * BLUE  + LIGHTCYAN;
    high = 16 * GREEN + WHITE;
    write_list_box( i, norm, high );
}

/*------------------------------------------------------------------------*
 *  "update_list_item" changes the item selected in an active list control.
 *
 *  returns:  nothing
 */
void dialog::update_list_item( int i,           // index number of control
                               int key )        // keyboard entry
{
    int norm, high;

    switch( key )
    {
    case HOME:
        ctrl[i].item = 0;
        break;

    case END:
        ctrl[i].item = ctrl[i].size - 1;
        break;

    case UP_ARROW:
        if( ctrl[i].item > 0 )
            ctrl[i].item--;
        break;

    case DN_ARROW:
        if( ctrl[i].item < ctrl[i].size - 1 )
            ctrl[i].item++;
        break;
    }

    if( ctrl[i].item - ctrl[i].top > 7 )
        ctrl[i].top = ctrl[i].item - 7;
    else if( ctrl[i].item - ctrl[i].top < 0 )
        ctrl[i].top = ctrl[i].item;

    norm = 16 * BLUE  + LIGHTCYAN;
    high = 16 * GREEN + WHITE;
    write_list_box( i, norm, high );
}

/*------------------------------------------------------------------------*
 *  "change_list" changes the complete list in a list control.
 *
 *  returns:  nothing
 */
void dialog::change_list( int i,                // index number of control
                          char *list,           // list of strings
                          int  wdth,            // width of list
                          int  size )           // items in list
{
    ctrl[i].list   = list;
    ctrl[i].wdth   = wdth;
    ctrl[i].size   = size;
    ctrl[i].item   = 0;
    ctrl[i].top    = 0;
}

/*------------------------------------------------------------------------*
 *  "normal_text" writes the text of a text control.
 *
 *  returns:  nothing
 */
void dialog::normal_text( int i )               // index number of control
{
    int text;
    int j;

    text = 16 * LIGHTGRAY + BLACK;
    j = format_message( dialog_buffer, ctrl[i].text, text, 0 );
    puttext( x + ctrl[i].x,            y + ctrl[i].y,
             x + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "update_text" re-writes the text of a text control.
 *
 *  returns:  nothing
 */
void dialog::update_text( int i,                // index number of control
                          char *ptr )           // pointer to new text 
{
    int text;
    int j;

    text = 16 * LIGHTGRAY + BLACK;
    ctrl[i].text = ptr;
    j = format_message( dialog_buffer, ctrl[i].text, text, 0 );
    puttext( x + ctrl[i].x,         y + ctrl[i].y,
             x + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "set_cbox" sets the check box control.
 *
 *  returns:  nothing
 */
void dialog::set_cbox( int i )                  // index number of control
{
    ctrl[i].check = 1;

    gettext( x + ctrl[i].x,     y + ctrl[i].y,
             x + ctrl[i].x + 2, y + ctrl[i].y,
             dialog_buffer );

    dialog_buffer[2] = 'X';

    puttext( x + ctrl[i].x,     y + ctrl[i].y,
             x + ctrl[i].x + 2, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "clear_cbox" clears the check box control.
 *
 *  returns:  nothing
 */
void dialog::clear_cbox( int i )                // index number of control
{
    ctrl[i].check = 0;

    gettext( x + ctrl[i].x,     y + ctrl[i].y,
             x + ctrl[i].x + 2, y + ctrl[i].y,
             dialog_buffer );

    dialog_buffer[2] = ' ';

    puttext( x + ctrl[i].x,     y + ctrl[i].y,
             x + ctrl[i].x + 2, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "disable_cbox" disables the check box control.
 *
 *  returns:  nothing
 */
void dialog::disable_cbox( int i )              // index number of control
{
    ctrl[i].check = -1;

    gettext( x + ctrl[i].x,     y + ctrl[i].y,
             x + ctrl[i].x + 2, y + ctrl[i].y,
             dialog_buffer );

    dialog_buffer[2] = '-';

    puttext( x + ctrl[i].x,     y + ctrl[i].y,
             x + ctrl[i].x + 2, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "return_cbox" returns the current setting of the check box control.
 *
 *  returns:  nothing
 */
int dialog::return_cbox( int i )                // index number of control
{
    return( ctrl[i].check );
}

/*------------------------------------------------------------------------*
 *  "normal_cbox" writes the text of a check box control.
 *
 *  returns:  nothing
 */
void dialog::normal_cbox( int i )               // index number of control
{
    int text, high;
    int j;
    char *box[3] = { "[-] ", "[ ] ", "[X] " };

    text = 16 * LIGHTGRAY + BLACK;
    high = 16 * LIGHTGRAY + YELLOW;

    assert( ctrl[i].check ==  1 ||
            ctrl[i].check ==  0 || 
            ctrl[i].check == -1 );

    j = format_message( dialog_buffer, box[ctrl[i].check+1], text, high );
    puttext( x + ctrl[i].x,         y + ctrl[i].y,
             x + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
    
    j = format_message( dialog_buffer, ctrl[i].text, text, high );
    puttext( x + 4 + ctrl[i].x,         y + ctrl[i].y,
             x + 4 + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "select_cbox" writes the text of a check box control.
 *
 *  returns:  nothing
 */
void dialog::select_cbox( int i )               // index number of control
{
    int text, high;
    int j;
    char *box[3] = { "[-] ", "[ ] ", "[X] " };

    text = 16 * LIGHTGRAY + WHITE;
    high = 16 * LIGHTGRAY + YELLOW;

    assert( ctrl[i].check ==  1 ||
            ctrl[i].check ==  0 || 
            ctrl[i].check == -1 );

    j = format_message( dialog_buffer, box[ctrl[i].check+1], text, high );
    puttext( x + ctrl[i].x,         y + ctrl[i].y,
             x + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
    
    j = format_message( dialog_buffer, ctrl[i].text, text, high );
    puttext( x + 4 + ctrl[i].x,         y + ctrl[i].y,
             x + 4 + ctrl[i].x + j - 1, y + ctrl[i].y,
             dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "normal_control" displays a normal control.
 *
 *  returns:  nothing
 */
void dialog::normal_control( int i )            // control id number
{
    if( ctrl[i].ctrl == PUSH_CTRL )
        normal_button( i );
    else if( ctrl[i].ctrl == EDIT_CTRL )
        normal_edit( i );
    else if( ctrl[i].ctrl == LIST_CTRL )
        normal_list( i );
    else if( ctrl[i].ctrl == CBOX_CTRL )
        normal_cbox( i );
}

/*------------------------------------------------------------------------*
 *  "select_control" displays a selected control.
 *
 *  returns:  nothing
 */
void dialog::select_control( int i )            // control id number
{
    if( ctrl[i].ctrl == PUSH_CTRL )
        select_button( i );
    else if( ctrl[i].ctrl == EDIT_CTRL )
        select_edit( i );
    else if( ctrl[i].ctrl == LIST_CTRL )
        select_list( i );
    else if( ctrl[i].ctrl == CBOX_CTRL )
        select_cbox( i );
}

/*------------------------------------------------------------------------*
 *  "update_control" sends a key code to a control.
 *
 *  returns:  nothing
 */
void dialog::update_control( int i,             // control id number
                             int k )            // key code
{
    if( ctrl[i].ctrl == EDIT_CTRL )
        update_edit_data( i, k );
    else if( ctrl[i].ctrl == LIST_CTRL )
        update_list_item( i, k );
}

/*------------------------------------------------------------------------*
 *  "paint_border" displays a border around selected controls in a 
 *  dialog box.
 *
 *  returns:  nothing
 */
void dialog::paint_border( int left,            // border edges
                           int top, 
                           int right, 
                           int bottom )
{
    int i, height, width;

    width  = right - left + 1;
    height = bottom - top + 1;

    for( i = 0; i < width; i++ )
    {
        dialog_buffer[2*i] = HORZ1;
        dialog_buffer[2*i+1] = 16 * LIGHTGRAY + BLACK;
    }

    dialog_buffer[0]         = LF_TOP1;
    dialog_buffer[2*width-2] = RT_TOP1;
    puttext( x + left,  y + top, 
             x + right, y + top, dialog_buffer );

    dialog_buffer[0]         = LF_BOT1;
    dialog_buffer[2*width-2] = RT_BOT1;
    puttext( x + left,  y + bottom, 
             x + right, y + bottom, dialog_buffer );

    for( i = 0; i < height; i++ )
    {
        dialog_buffer[2*i] = VERT1;
        dialog_buffer[2*i+1] = 16 * LIGHTGRAY + BLACK;
    }

    puttext( x + left,  y + top + 1, 
             x + left,  y + bottom - 1, dialog_buffer );
    puttext( x + right, y + top + 1, 
             x + right, y + bottom - 1, dialog_buffer );
}

/*------------------------------------------------------------------------*
 *  "paint_dialog" displays a dialog box background, border, and shadow.
 *
 *  returns:  -1 on failure, else control selected
 */
int dialog::paint_dialog()
{
    int i, j, need, select;

    Console.mouse_cursor_off();

    // setup screen buffers
    gettext( x, y, x + dx + 1, y + dy + 1, Text_buffer );

    need = 2 * ( dx + 2 ) * ( dy + 2 );
    assert( need < DIALOG_BUFFER );
    memset( dialog_buffer, 0, need );

    for( i = 0; i < need; i++ )
        dialog_buffer[2*i+1] = 16 * LIGHTGRAY + BLACK;

    puttext( x, y, x + dx, y + dy, dialog_buffer );

    for( i = 0; i < dx + 1; i++ )
    {
        dialog_buffer[2*i]   = HORZ2;
        dialog_buffer[2*i+1] = 16 * LIGHTGRAY + WHITE;
    }

    dialog_buffer[0]    = LF_TOP2;
    dialog_buffer[2*dx] = RT_TOP2;
    puttext( x, y, x + dx, y, dialog_buffer );

    dialog_buffer[0]    = LF_BOT2;
    dialog_buffer[2*dx] = RT_BOT2;
    puttext( x, y + dy, x + dx, y + dy, dialog_buffer );

    for( i = 0; i < dy + 1; i++ )
    {
        dialog_buffer[2*i]   = VERT2;
        dialog_buffer[2*i+1] = 16 * LIGHTGRAY + WHITE;
    }

    puttext( x,      y + 1, x,      y + dy - 1, dialog_buffer );
    puttext( x + dx, y + 1, x + dx, y + dy - 1, dialog_buffer );

    // add the title
    j = strlen( title ) + 2;
    dialog_buffer[0] = ' ';
    for( i = 0; i < j; i++ )
        dialog_buffer[2*(i+1)] = title[i];
    dialog_buffer[2*(i+1)] = ' ';

    puttext( x + ( dx / 2 ) - ( j / 2 ), y,
             x + ( dx / 2 ) + ( j / 2 ) - 1 + j % 2, y,
             dialog_buffer );

    // right shadow
    gettext( x + dx + 1, y + 1, x + dx + 1, y + dy, dialog_buffer );
    for( i = 0; i <= dy; i++ )
        dialog_buffer[2*i+1] = BLACK*16 + DARKGRAY;
    puttext( x + dx + 1, y + 1, x + dx + 1, y + dy, dialog_buffer );

    // bottom shadow
    gettext( x + 1, y + dy + 1, x + dx + 1, y + dy + 1, dialog_buffer );
    for( i = 0; i <= dx; i++ )
        dialog_buffer[2*i+1] = BLACK*16 + DARKGRAY;
    puttext( x + 1, y + dy + 1, x + dx + 1, y + dy + 1, dialog_buffer );

    select = init_dialog();

    Console.mouse_cursor_on();

    return( select );
}

/*------------------------------------------------------------------------*
 *  "erase_dialog" restores the video display on closing a dialog.
 *
 *  returns:  nothing
 */
void dialog::erase_dialog()
{
    Console.mouse_cursor_off();
    puttext( x, y, x + dx + 1, y + dy + 1, Text_buffer );
    Console.mouse_cursor_on();
}

/*------------------------------------------------------------------------*
 *  "init_dialog" displays and initializes dialog controls.
 *
 *  returns:  initial control number
 */
int dialog::init_dialog()
{
    int i, select;

    // show controls
    for( i = 0; i < count; i++ )
    {
        if( ctrl[i].ctrl == TEXT_CTRL )
            normal_text( i );
        else
            normal_control( i );
    }

    // initialize control selection
    select = 0;
    for( i = 0; i < count; i++ )
    {
        if( i == select )
        {
            if( ctrl[i].ctrl == TEXT_CTRL )
                select++;
            else
                select_control( select );
        }
    }

    return( select );
}

/*------------------------------------------------------------------------*
 *  "shift_tab_select" switches the selected control on Shift+Tab keys.
 *
 *  returns:  selected control number
 */
int dialog::shift_tab_select( int i )           // current control
{
    normal_control( i );

    i--;
    if( i < 0 )
        i = count - 1;

    while( ctrl[i].ctrl == TEXT_CTRL )
    {
        i--;
        if( i < 0 )
            i = count - 1;
    }

    select_control( i );

    return( i );
}

/*------------------------------------------------------------------------*
 *  "tab_select" switches the selected control on Tab key.
 *
 *  returns:  selected control number
 */
int dialog::tab_select( int i )                 // current control
{
    normal_control( i );

    i++;
    if( i >= count )
        i = 0;

    while( ctrl[i].ctrl == TEXT_CTRL )
    {
        i++;
        if( i >= count )
            i = 0;
    }

    select_control( i );

    return( i );
}

/*------------------------------------------------------------------------*
 *  "alt_key_select" switches the selected control on Alt+letter keys.
 *
 *  returns:  selected control number
 */
int dialog::alt_key_select( int i,              // current control
                            int code )          // key code
{
    int k;

    for( k = 0; k < count; k++ )
    {
        if( code == ctrl[k].key && k != i )
        {
            normal_control( i );
            i = k;
            select_control( i );
            break;
        }
    }

    return( i );
}

| home | contents | previous | next page | send comment | send link | add bookmark |

Copyright © 2004, Stephen R. Schmitt