uidialog.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,347 行 · 第 1/3 页

C
1,347
字号
                }
                if( vs->area.col + col < PrevCol ) {
                    new_area.col = 0;
                } else {
                    new_area.col = vs->area.col + col - PrevCol;
                }
                new_area.width = vs->area.width;
                new_area.height = vs->area.height;
                prev_row = vs->area.row;
                prev_col = vs->area.col;
                uiresizedialog( info, &new_area );
                /* new_area may have been adjusted */
                PrevRow += new_area.row - prev_row;
                PrevCol += new_area.col - prev_col;
            }
            new_ev = EV_NO_EVENT;
        }
        break;
    case EV_MOUSE_RELEASE :
        if( info->moving ) {
            info->moving = FALSE;
            new_ev = EV_NO_EVENT;
        }
    }
    return( new_ev );
}

static EVENT uitabkey( EVENT ev, a_dialog *info )
{
    VFIELD          *curr, *fld;
    ORD             row, col;
    SAREA           area;
    EVENT           newev;

    if( info->first == NULL ) return( FALSE );
    curr = info->curr;
    newev = ev;
    switch( ev ){
    case EV_MOUSE_DCLICK:
    case EV_MOUSE_PRESS:
    {
        a_combo_box         *combo;
        a_list              *list;
        VSCREEN             *mousevs;

        mousevs = uivmousepos( info->vs, &row, &col );
        fld = info->first;
        while( fld != NULL ) {
            list = NULL;
            area = fld->area;
            if( fld->typ == FLD_PULLDOWN ) {
                list = fld->ptr;
                area.height = 1;
                area.width += 1;    /* pulldown button */
            } else if( fld->typ == FLD_LISTBOX ) {
                list = fld->ptr;
            } else if( fld->typ == FLD_EDIT_MLE ) {
                list = fld->ptr;
            } else if( fld->typ == FLD_COMBOBOX ) {
                area.height = 1;
                area.width += 2;    /* pulldown button */
                combo = fld->ptr;
                list = &combo->list;
            }
            if( mousevs != info->vs ) {
                if( list != NULL && list->box != NULL ) {
                    if( list->box->vs == mousevs ) {
                        break;
                    }
                }
            } else if( row >= area.row  && row < area.row + area.height &&
                        col >= area.col  && col < area.col + area.width ) {
                break;
            }
            fld = nextfield( fld );
        }
        /* check boxes don't get mouse events unless mouse over them */
        if( fld == NULL && curr != NULL && curr->typ == FLD_CHECK ) {
            newev = EV_NO_EVENT;
        } else {
            curr = fld;
        }
        break;
    }
    case EV_TAB_FORWARD :
        curr = forwardtab( info );
        break;
    case EV_TAB_BACKWARD :
        curr = backwardtab( info );
        break;
    case EV_CURSOR_RIGHT :
    case EV_CURSOR_DOWN :
    {
        a_radio             *r1, *r2;

        if( curr!= NULL && curr->typ == FLD_RADIO ) {
            fld = nextfield( curr );
            if( fld != NULL ) {
                r1 = curr->ptr;
                r2 = fld->ptr;
                if( r1->group == r2->group ) {
                    curr = fld;
                    do_radio( info, fld );
                    newev = EV_CHECK_BOX_CLICK;
                }
            }
        }
        break;
    }
    case EV_CURSOR_LEFT :
    case EV_CURSOR_UP :
    {
        a_radio             *r1, *r2;

        if( curr!= NULL && curr->typ == FLD_RADIO ) {
            if( curr != info->first ) {
                fld = curr - 1;
                r1 = curr->ptr;
                r2 = fld->ptr;
                if( r1->group == r2->group ) {
                    curr = fld;
                    do_radio( info, fld );
                    newev = EV_CHECK_BOX_CLICK;
                }
            }
        }
        break;
    }
    }
    if( info->curr != curr ) {
        uidialogsetcurr( info, curr );
    }
    return( newev );
}

EVENT uihotkeyfilter( a_dialog *info, EVENT ev )
{
    char        ch, hotkey;
    VFIELD      *vf;

    /* is the event a key press or alt-key press */
    if( ev < 0x100 && isalpha( ev ) ) {
        ch = tolower( ev );
    } else {
        ch = uialtchar( ev );
    }

    if( ch ) {
        hotkey = '\0';
        for( vf = info->fields ; vf->typ != FLD_VOID; ++vf ){
            switch( vf->typ ) {
                case FLD_HOT:
                    hotkey = (char)((a_hot_spot *)vf->ptr)->flags & HOT_CHAR;
                    break;
                case FLD_CHECK:
                    hotkey = (char)((a_check *)vf->ptr)->hotkey;
                    break;
                case FLD_RADIO:
                    hotkey = (char)((a_radio *)vf->ptr)->hotkey;
                    break;
                default:
                    hotkey = '\0';
            }
            if( hotkey == ch ) {
                break;
            }
        }

        /* make sure the new field is hilighted */
        if( info->curr != vf && vf->typ != FLD_VOID ) {
            uidialogsetcurr( info, vf );
        }

        if( hotkey == ch ) {
            switch( vf->typ ) {
                case FLD_HOT:
                    ev = ((a_hot_spot *)vf->ptr)->event;
                    break;
                case FLD_CHECK:
                    info->dirty = TRUE;
                    ((a_check *)vf->ptr)->val = !((a_check *)vf->ptr)->val;
                    print_field( info->vs, vf, TRUE );
                    ev = EV_CHECK_BOX_CLICK;
                    break;
                case FLD_RADIO:
                    do_radio( info, vf );
                    ev = EV_CHECK_BOX_CLICK;
                    break;
            }
        }
    }

    return( ev );
}

EVENT uiprocessdialogevent( EVENT ev, a_dialog *info )
{
    VFIELD              *field;
    a_check             *check;
    an_edit_control     *edit;
    unsigned            choice;
    a_combo_box         *combo;
    a_list              *list;

    ev = uicheckmove( ev, info );
    ev = uitabkey( ev, info );
    field = info->curr;
    if( field != NULL ) {
        switch( field->typ ) {
        case FLD_CHECK:
        case FLD_RADIO:
            switch( ev ) {
            case EV_MOUSE_DCLICK:
            case EV_MOUSE_PRESS:
            case ' ' :
                ev = EV_CHECK_BOX_CLICK;
                if( field->typ == FLD_RADIO ) {
                    do_radio( info, field );
                    break;
                }
                if( field->typ == FLD_CHECK ) {
                    info->dirty = TRUE;
                    check = field->ptr;
                    check->val = !check->val;
                    print_field( info->vs, field, TRUE );
                    break;
                }
            }
            break;
        case FLD_EDIT:
        case FLD_INVISIBLE_EDIT:
            ev = uiledit( ev );
            edit = field->ptr;
            if( info->edit_data != NULL ) {
                edit->buffer = info->edit_data->edit_buffer;
                edit->length = info->edit_data->edit_eline.length;
            }
            break;
        case FLD_LISTBOX:
        case FLD_EDIT_MLE:
            list = field->ptr;
            ev = uilistbox( ev, list, TRUE );
            break;
        case FLD_PULLDOWN:
            list = field->ptr;
            if( list->box == NULL ) {
                ev = pulldownfilter( ev, info );
            } else {
                choice = list->choice;
                ev = uilistbox( ev, list, FALSE );
                if( choice != list->choice ) {
                    info->dirty = TRUE;
                    print_field( info->vs, field, TRUE );
                }
            }
            break;
        case FLD_COMBOBOX:
            combo = field->ptr;
            list  = &combo->list;
            edit  = &combo->edit;
            if( list->box == NULL ) {
                ev = pulldownfilter( ev, info );
            } else {
                choice = list->choice;
                ev = uilistbox( ev, list, combo->perm );
                if( choice != list->choice ) {
                    info->dirty = TRUE;
                    setcombobuffer( info, field );
                    print_field( info->vs, field, TRUE );
                }
            }
            ev = uiledit( ev );
            if( info->edit_data != NULL ) {
                edit->buffer = info->edit_data->edit_buffer;
                edit->length = info->edit_data->edit_eline.length;
            }
            break;
        }
    }
    ev = uihotkeyfilter( info, ev );
    ev = uihotspotfilter( info->vs, info->fields, ev );
    return( ev );
}

an_event uidialog( a_dialog *info )
{
    static EVENT    dialog_events[] = {
        'a',            'z',
        'A',            'Z',
        EV_ALT_Q,       EV_ALT_M,
        EV_NO_EVENT,
        EV_ALT_CURSOR_DOWN,
        EV_CURSOR_UP,   EV_CURSOR_DOWN,
        EV_CURSOR_LEFT, EV_CURSOR_RIGHT,
        EV_TAB_FORWARD, EV_TAB_BACKWARD,
        EV_MOUSE_PRESS, EV_MOUSE_RELEASE,
        EV_MOUSE_DRAG,  EV_MOUSE_REPEAT,
        EV_MOUSE_DCLICK,
        EV_ENTER,       ' ',
        EV_NO_EVENT
    };
    a_list      *list;
    an_event    ev;
    VFIELD      *field;

    ev = EV_NO_EVENT;
    enter_field( info, info->curr );

    while( ev == EV_NO_EVENT || !uiinlist( ev ) ) {
        field = info->curr;
        if( field != NULL ) {
            switch( field->typ ) {
                case FLD_EDIT:
                case FLD_INVISIBLE_EDIT:
                    uieditpushlist();
                    break;
                case FLD_PULLDOWN:
                    uiboxpushlist( );
                    break;
                case FLD_COMBOBOX:
                    uiboxpushlist( );
                    uieditpushlist();
                    break;
                case FLD_LISTBOX:
                case FLD_EDIT_MLE:
                    list = field->ptr;
                    uiboxpushlist();
                    break;
            }
        }
        uipushlist( dialog_events );
        ev = uidialogevent( info->vs );
        ev = uidialogcallback( info, ev );
        uipoplist( /* dialog_events */ );

        if( field != NULL ) {
            switch( field->typ ) {
            case FLD_EDIT:
            case FLD_INVISIBLE_EDIT:
                uieditpoplist();
                break;
            case FLD_PULLDOWN:
                uiboxpoplist();
                break;
            case FLD_COMBOBOX:
                uiboxpoplist();
                uieditpoplist();
                break;
            case FLD_LISTBOX:
            case FLD_EDIT_MLE:
                uiboxpoplist();
                break;
            }
        }
        ev = uiprocessdialogevent( ev, info );
    }
    /* This code will make sure to exit the current fields before returning
     * a default hot spot event. This is for consistency with windows.
     */
    if( uiisdefaulthotspot( info->fields, ev ) ) {
        if( exit_field( info, info->curr ) ) {
            info->dirty = TRUE;
        }
    }
    info->field = (VFIELD *)info->curr - (VFIELD *)info->fields;
    return( ev );
}

void uifreedialog( a_dialog  *info )
{
    VFIELD              *fields;  // pointer to array of fields in dialog box
    a_list              *list;
    short unsigned      i;
    a_combo_box         *combo;
//  an_edit_control     *edit;

    fields = info->fields;

    exit_field( info, info->curr );
    for( i = 0 ; fields[i].typ != FLD_VOID ; ++i ) {
        switch( fields[i].typ ) {
            case FLD_LISTBOX:
            case FLD_PULLDOWN:
            case FLD_EDIT_MLE:
                list = fields[i].ptr;
                uiendlistbox( list );
                break;
//          case FLD_INVISIBLE_EDIT:
//          case FLD_EDIT:
//              edit = fields[i].ptr;
//              uifree( edit->buffer );
//              edit->buffer = NULL;            //  Need this null for next
//              break;                          //  time around
            case FLD_COMBOBOX:
                combo = fields[i].ptr;
                list = &combo->list;
//              edit = &combo->edit;
//              uifree( edit->buffer );
//              edit->buffer = NULL;
                uiendlistbox( list );       // Shut down listbox
                break;
        }
    }
}

void uienddialog( a_dialog  *info )
{
    uifreedialog( info );
    uifinidialog( info->vs );
    uifree( info );
}

#if 0
void uifreefields( VFIELD *fields )
{
    short unsigned      i;
    a_combo_box         *combo;
    an_edit_control     *edit;

    for( i = 0 ; fields[i].typ != FLD_VOID ; ++i ) {
        switch( fields[i].typ ) {
        case FLD_INVISIBLE_EDIT:
        case FLD_EDIT:
            edit = fields[i].ptr;
            uifree( edit->buffer );
            edit->buffer = NULL;                //  Need this null for next
            break;                              //  time around
        case FLD_COMBOBOX:
            combo = fields[i].ptr;
            edit = &combo->edit;
            uifree( edit->buffer );
            edit->buffer = NULL;
            break;
        }
    }
}
#endif

bool uidialogisdirty( a_dialog *info )
{
    uidialogexitcurr( info );
    return( info->dirty );
}

void uidialogsetdirty( a_dialog *info, bool dirty )
{
    info->dirty = dirty;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?