uidialog.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,347 行 · 第 1/3 页
C
1,347 行
if( field->typ == FLD_COMBOBOX ) {
combo = field->ptr;
edit = &combo->edit;
} else {
edit = field->ptr;
}
if( info->edit_data == NULL ) {
info->edit_data = uibegedit( info->vs, area.row, area.col, area.width,
UIData->attrs[ ATTR_CURR_EDIT ],
edit->buffer, edit->length, 0, 0, TRUE, 0,
field->typ == FLD_INVISIBLE_EDIT );
}
break;
case FLD_LISTBOX :
list = field->ptr;
list->box->attr = ATTR_CURR_EDIT;
uipaintlistbox( list );
break;
case FLD_EDIT_MLE :
list = field->ptr;
list->box->attr = ATTR_NORMAL;
uipaintlistbox( list );
break;
}
}
void uireinitdialog( a_dialog *info, VFIELD *fields )
{
unsigned i;
uiposnhotspots( info->vs, fields );
info->dirty = FALSE;
info->first = NULL;
info->other = NULL;
info->fields = fields;
info->first = &fields[0];
/* set first to be first field in tab sequence */
while( notintab( info->first ) ) {
if( info->first->typ == FLD_VOID ) {
info->first = NULL;
break;
}
++(info->first);
}
info->curr = info->first;
if( info->first != NULL ) {
/* set curr to first field in tab sequence not an unset radio button */
while( radiooff( info->curr ) ) {
info->curr = nextfield( info->curr );
}
}
for( i = 0 ; fields[i].typ != FLD_VOID ; ++i ) {
print_field( info->vs, &fields[i], &fields[i] == info->curr );
}
enter_field( info, info->curr );
}
bool uigetdialogarea( a_dialog *dialog, SAREA *area )
{
VSCREEN *vs;
if( dialog != NULL && area != NULL ) {
vs = (VSCREEN *)dialog->vs;
*area = vs->area;
return( TRUE );
}
return( FALSE );
}
void *uibegdialog( char *title, VFIELD *fields, ORD rows, ORD cols, int rpos, int cpos )
{
char *lines[1];
a_dialog *info;
lines[ 0 ] = NULL;
info = uicalloc( 1, sizeof( a_dialog ) );
if( info == NULL ) {
return( NULL );
}
info->vs = uiinitdialog( title, UIData->attrs[ ATTR_NORMAL ],
lines, rows, cols, rpos, cpos );
uireinitdialog( info, fields );
return( info );
}
static void do_radio( a_dialog *info, VFIELD *field )
{
a_radio *cur_radio;
VFIELD *fields;
a_radio *radio;
int i;
fields = info->fields;
// might want to use info->first, kind of unsure
cur_radio = field->ptr;
if( cur_radio->value == cur_radio->group->value ) return;
info->dirty = TRUE;
for( i = 0 ; fields[i].typ != FLD_VOID ; ++i ) {
if( fields[i].typ == FLD_RADIO ) {
radio = fields[i].ptr;
if( radio->group == cur_radio->group &&
radio->value == radio->group->value ) {
radio->group->value = cur_radio->value;
print_field( info->vs, &fields[i], FALSE );
break;
}
}
}
cur_radio->group->value = cur_radio->value;
print_field( info->vs, field, TRUE );
}
void uiupdatecombobox( a_combo_box *combo )
{
char *str;
a_list *list;
an_edit_control *edit;
edit = &combo->edit;
list = &combo->list;
str = (char *)uimalloc( CTRL_BUF_LEN );
if( str != NULL ) {
if( (*list->get)( list->data, list->choice, str, CTRL_BUF_LEN ) ) {
uifree( edit->buffer );
edit->buffer = str;
edit->length = strlen( str );
} else {
uifree( str );
}
}
}
void uiupdateedit( a_dialog *info, VFIELD *field )
{
an_edit_control *edit;
a_combo_box *combo;
if( ( field == NULL ) || ( info == NULL ) || ( field != info->curr ) ) {
return;
}
edit = NULL;
switch( field->typ ) {
case FLD_COMBOBOX :
combo = field->ptr;
edit = &combo->edit;
break;
case FLD_EDIT :
case FLD_INVISIBLE_EDIT:
edit = field->ptr;
break;
}
if( edit != NULL ) {
if( info->edit_data != NULL ) {
uiendedit();
info->edit_data = NULL;
}
enter_field( info, info->curr );
}
}
static void setcombobuffer( a_dialog *info, VFIELD *fld )
{
a_combo_box *combo;
an_edit_control *edit;
combo = fld->ptr;
edit = &combo->edit;
uiupdatecombobox( combo );
if( info->edit_data != NULL ) {
info->edit_data->edit_buffer = edit->buffer;
info->edit_data->edit_eline.buffer = edit->buffer;
info->edit_data->edit_eline.length = edit->length;
info->edit_data->edit_eline.update = TRUE;
info->edit_data->edit_eline.index = 0;
info->edit_data->edit_eline.scroll = 0;
}
}
EVENT pulldownfilter( EVENT ev, a_dialog *info )
{
a_list *list = NULL;
a_combo_box *combo;
VSCREEN *vs;
SAREA area;
VFIELD *fld;
fld = info->curr;
if( fld->typ == FLD_PULLDOWN ) {
list = fld->ptr;
} else if( fld->typ == FLD_COMBOBOX ) {
combo = fld->ptr;
list = &combo->list;
}
if( list->get == NULL ) {
list->get = ( bool (*) ( void *, unsigned, char *, unsigned ) )
uigetlistelement; // set get_element function
}
switch( ev ) {
case EV_MOUSE_DCLICK:
case EV_MOUSE_PRESS:
{
ORD row, col;
uivmousepos( info->vs, &row, &col );
area = fld->area;
area.width += 1; /* extra column for button */
if( fld->typ == FLD_COMBOBOX ) {
/* mouse press must be on little button at right */
area.col += area.width;
area.width = 1;
}
if( fld->typ == FLD_COMBOBOX || fld->typ == FLD_PULLDOWN ) {
/* mouse press must be on top line */
area.height = 1;
}
if( row < area.row || row >= area.row + area.height ) break;
if( col < area.col || col >= area.col + area.width ) break;
/* FALLS into next case */
}
case EV_CURSOR_DOWN:
case EV_ALT_CURSOR_DOWN:
/* list->box must be null */
area = fld->area;
vs = info->vs;
area.row += ( vs->area.row + 2 );
area.col += vs->area.col;
if( fld->typ == FLD_COMBOBOX ) {
area.col++;
}
if( area.row + area.height >= UIData->height ) {
area.row -= area.height + 3;
}
vs = uiopen( &area, NULL, V_DIALOGUE | V_LISTBOX );
area.row = 0;
area.col = 0;
list->box = uibeglistbox( vs, &area, list );
if( ev != EV_MOUSE_PRESS && ev != EV_MOUSE_DCLICK
&& fld->typ == FLD_COMBOBOX ) {
info->dirty = TRUE;
setcombobuffer( info, fld );
print_field( info->vs, fld, TRUE );
}
break;
}
return( ev );
}
static void *forwardtab( a_dialog *info )
{
VFIELD *fld;
if( info->curr == NULL ){
fld = info->first;
} else {
fld = nextfield( info->curr );
if( fld == NULL ) {
fld = info->first;
}
}
while( radiooff( fld ) ) {
fld = nextfield( fld );
}
return( fld );
}
static void *backwardtab( a_dialog *info )
{
VFIELD *fld, *hold;
hold = NULL;
fld = info->first;
while( fld != info->curr ) {
if( !radiooff( fld ) ) {
hold = fld;
}
fld = nextfield( fld );
}
if( hold == NULL ) { /* wrap */
while( fld != NULL ) {
if( !radiooff( fld ) ) {
hold = fld;
}
fld = nextfield( fld );
}
}
return( hold );
}
extern void uidialogexitcurr( a_dialog *info )
{
/* you must call this function to set info->dirty or to do */
/* blank trimming on an edit control */
if( exit_field( info, info->curr ) ) {
info->dirty = TRUE;
}
}
extern void uidialogsetcurr( a_dialog *info, VFIELD *curr )
{
VFIELD *other;
other = info->curr;
if( other != curr ) {
info->other = info->curr;
info->curr = curr;
if( exit_field( info, other ) ) {
info->dirty = TRUE;
}
print_field( info->vs, other, FALSE );
enter_field( info, curr );
print_field( info->vs, curr, TRUE );
uidialogchangefield( info );
}
}
void uimovefield( a_dialog *info, VFIELD *curr, int row_diff, int col_diff )
{
a_combo_box *combo;
a_list *list;
info = info;
switch( curr->typ ) {
case FLD_COMBOBOX :
combo = curr->ptr;
if( combo->perm ) {
uimovelistbox( &combo->list, row_diff, col_diff );
} else {
uiendlistbox( &combo->list );
}
break;
case FLD_LISTBOX :
case FLD_EDIT_MLE :
list = (a_list *)curr->ptr;
uimovelistbox( list, row_diff, col_diff );
if( list->box != NULL ) {
uivsetactive( list->box->vs );
}
break;
case FLD_PULLDOWN :
uiendlistbox( (a_list *)curr->ptr );
break;
}
}
void uiredrawdialog( a_dialog *info )
{
VSCREEN *vs;
int i;
vs = (VSCREEN *)info->vs;
uivclose( vs );
uivopen( vs );
for( i = 0 ; info->fields[i].typ != FLD_VOID ; ++i ) {
print_field( info->vs, &info->fields[i],
&info->fields[i] == info->curr );
}
}
bool uiresizedialog( a_dialog *info, SAREA *new_area )
{
int row_diff;
int col_diff;
VSCREEN *vs;
VFIELD *curr;
int i;
bool resize;
vs = (VSCREEN *)info->vs;
if( new_area->row < 2 ) {
new_area->row = 2;
}
if( new_area->col < 1 ) {
new_area->col = 1;
}
if( new_area->row + vs->area.height >= UIData->height ) {
new_area->row = UIData->height - vs->area.height - 1;
}
if( new_area->col + vs->area.width >= UIData->width ) {
new_area->col = UIData->width - vs->area.width - 1;
}
row_diff = new_area->row - vs->area.row;
col_diff = new_area->col - vs->area.col;
resize = ( new_area->width != vs->area.width ) ||
( new_area->height != vs->area.height );
if( resize ) {
uivclose( vs );
vs->area = *new_area;
uivopen( vs );
} else {
uivmove( info->vs, new_area->row, new_area->col );
}
/* close all open pull down boxes */
for( curr = info->fields; curr->typ != FLD_VOID; curr++ ) {
uimovefield( info, curr, row_diff, col_diff );
}
if( resize ) {
for( i = 0 ; info->fields[i].typ != FLD_VOID ; ++i ) {
print_field( info->vs, &info->fields[i],
&info->fields[i] == info->curr );
}
}
return( TRUE );
}
static ORD PrevRow = 0;
static ORD PrevCol = 0;
static EVENT uicheckmove( EVENT ev, a_dialog *info )
{
EVENT new_ev;
ORD row;
ORD col;
SAREA new_area;
VSCREEN *vs;
int prev_row;
int prev_col;
new_ev = ev;
switch( ev ) {
case EV_MOUSE_PRESS :
if( uivmousepos( NULL, &row, &col ) == info->vs ) {
vs = (VSCREEN *)info->vs;
if( ( row + 1 ) == vs->area.row ) { /* because it's framed */
PrevRow = row;
PrevCol = col;
info->moving = TRUE;
new_ev = EV_NO_EVENT;
}
}
break;
case EV_MOUSE_DRAG :
if( info->moving ) {
uivmousepos( NULL, &row, &col );
if( ( row != PrevRow ) || ( col != PrevCol ) ) {
vs = (VSCREEN *)info->vs;
if( vs->area.row + row < PrevRow ) {
new_area.row = 0;
} else {
new_area.row = vs->area.row + row - PrevRow;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?