uilstbox.c

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

C
522
字号
    if( list->box == NULL ) return( 0 );
    uiclose( list->box->vs );   // Shut down VSCREEN
    k = list->box->line;
    uifinigadget( &list->box->gadget );
    uifree( list->box );
    list->box = NULL;
    return( k );
}

static int getmouseregion( a_list *list, int *row, int *col )
{
    a_list_info     *box;

    box  = list->box;

    uimousepos( box->vs, row, col );

    if( *row - box->area.row >= (int)uilistsize( list ) ) {
        return( R_UNS );
    }
    if( *row >= box->area.height + box->area.row ) {
        return( R_DOWN );
    }
    if( *row < box->area.row ) {
        return( R_UP );
    }
    if( ( *col >= box->area.col + box->area.width ) ||
        ( *col <  box->area.col ) ) {
        return( R_UNS );
    }
    return( R_SEL );
}


EVENT charselect( EVENT ev, a_list *list )
{
    int         num;
    int         i;
    char        typed;

    typed = (char)ev;
    if( isupper( typed ) ) {
        typed = tolower( typed );
    }
    num = uilistsize( list );
    for( i = list->choice + 1; i < num; i++ ) {
        if( checkitem( list, typed, i ) ) {
            return( EV_LIST_BOX_CHANGED );
        }
    }
    for( i = 0; i < list->choice; i++ ) {
        if( checkitem( list, typed, i ) ) {
            return( EV_LIST_BOX_CHANGED );
        }
    }
    return( EV_NO_EVENT );
}

EVENT uilistbox( EVENT ev, a_list *list, bool permanent )
{
    int             listsize;
    int             maxline;
    int             newevent;
    a_list_info     *box;
    int             old_line;
    ORD             old_row;
    bool            close;

    if( Dclick ) {
        switch( ev ) {
        case EV_MOUSE_PRESS :
            Dclick = FALSE; /* must have gotten dlick without release */
            /* fall through */
        case EV_SCROLL_LINE_UP :
        case EV_SCROLL_LINE_DOWN :
        case EV_SCROLL_PAGE_UP :
        case EV_SCROLL_PAGE_DOWN :
        case EV_PAGE_UP :
        case EV_PAGE_DOWN :
        case EV_CURSOR_UP :
        case EV_CURSOR_DOWN :
            SelStart = FALSE;
            break;
        case EV_MOUSE_RELEASE :
            Dclick = FALSE;
            /* fall through */
        default :
            return( ev );
        }
    }
    close = FALSE;
    box = list->box;
    old_line = box->line;
    old_row = box->row;
    listsize = uilistsize( list );

    if( listsize > box->area.height ) {
        maxline = listsize - box->area.height;
    } else {
        maxline = 0;
    }

    if( maxline > 0 ) {
        ev = uigadgetfilter( ev, &box->gadget );
    }

    newevent = EV_NO_EVENT;
    switch( ev ) {
        case EV_MOUSE_DCLICK:
            Dclick = TRUE;
        case EV_MOUSE_PRESS:
        case EV_MOUSE_RELEASE:
        case EV_MOUSE_REPEAT:
        case EV_MOUSE_DRAG:
            {
                int         row, col, mpos;

                mpos = getmouseregion( list, &row, &col );
                newevent = ev;
                if( mpos == R_SEL ) {
                    SelStart = TRUE;
                    box->row  = (ORD) row - box->area.row;
                    box->row += box->line;
                }
                if( ev == EV_MOUSE_RELEASE ) {
                    if( mpos == R_SEL ) {
                        list->choice = list->box->row;
                        newevent = EV_LIST_BOX_CHANGED;
                    }
                    if( SelStart ) {
                        close = TRUE;
                        SelStart = FALSE;
                    }
                } else if( ev == EV_MOUSE_PRESS || ev == EV_MOUSE_DCLICK ) {
                    if( mpos == R_SEL ) {
                        if( ev == EV_MOUSE_DCLICK ) {
                            newevent = EV_LIST_BOX_DCLICK;
                        }
                    } else {
                        close = TRUE;
                    }
                } else if( mpos == R_UP  &&  box->line > 0  &&  SelStart ) {
                    box->line--;
                    box->row--;
                } else if( mpos == R_DOWN  &&  box->line < maxline ) {
                    box->line++;
                    box->row++;
                }
            }
            break;
        case EV_CURSOR_UP :
            if( box->row > 0 ) {
                if( box->row == box->line ) {
                    box->line--;
                }
                box->row--;
                list->choice = box->row;
                newevent = EV_LIST_BOX_CHANGED;
            }
            if( selectoutofrange( box ) ) {
                box->line = box->row;
                setstartline( list );
            }
            break;
        case EV_SCROLL_LINE_UP :
            if( box->line > 0 ) {
                box->line--;
            }
            break;
        case EV_CURSOR_DOWN :
            if( box->row < listsize - 1 ) {
                if( box->row - box->line == box->area.height - 1
                    && box->line < maxline ) {
                        ++box->line;
                }
                ++box->row;
                list->choice = box->row;
                newevent = EV_LIST_BOX_CHANGED;
            }
            if( selectoutofrange( box ) ) {
                box->line = box->row;
                setstartline( list );
            }
            break;
        case EV_SCROLL_LINE_DOWN :
            if( box->line < maxline ) {
                box->line++;
            }
            break;
        case EV_PAGE_UP :
            if( box->row == box->line ) {
                if( box->line < ( box->area.height - 1 ) ) {
                    box->line = 0;
                } else {
                    box->line -= ( box->area.height - 1 );
                }
                box->row -= old_line - box->line;
            } else {
                box->row = box->line;
            }
            if( box->row != old_row ) {
                list->choice = box->row;
                newevent = EV_LIST_BOX_CHANGED;
            }
            break;
        case EV_SCROLL_PAGE_UP :
            if( box->line < box->area.height ) {
                box->line = 0;
            } else {
                box->line -= box->area.height;
            }
            break;
        case EV_PAGE_DOWN :
            if( box->row == ( box->line + box->area.height - 1 ) ) {
                box->line += box->area.height - 1;
                if( box->line > maxline ) {
                    box->line = maxline;
                }
                box->row += ( box->line - old_line );
            } else {
                box->row = box->line + box->area.height - 1;
            }
            if( box->row != old_row ) {
                list->choice = box->row;
                newevent = EV_LIST_BOX_CHANGED;
            }
            break;
        case EV_SCROLL_PAGE_DOWN :
            box->line += box->area.height;
            if( box->line > maxline ) {
                box->line = maxline;
            }
            break;
        case EV_SCROLL_VERTICAL :
            box->line = box->gadget.pos;
            break;
        case EV_ALT_CURSOR_UP :
            close = TRUE;
            break;
        default :
            if( isalpha( ev ) ) {
                newevent = charselect( ev, list );
            } else {
                newevent = ev;
            }
            break;
    }
    if( ( old_line != box->line ) && ( maxline > 0 ) ) {
        uisetgadget( &box->gadget, box->line );
    }
    if( box->line != old_line || box->row != old_row ) {
        uipaintlistbox( list );
    }

    if( !permanent && close ) {
        uiendlistbox( list );
        newevent = EV_LIST_BOX_CLOSED;
    }
    return( newevent );
}

⌨️ 快捷键说明

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