uivfld.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 291 行
C
291 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <string.h>
#include "uidef.h"
#include "uivfld.h"
#include "uivedit.h"
#include "uiedit.h"
static EVENT livefieldevents[] = {
' ', '~',
EV_HOME, EV_DELETE,
EV_ALT_KEYPAD( 1 ), EV_ALT_KEYPAD( 0xff ),
EV_NO_EVENT, /* end of list of ranges */
EV_RUB_OUT,
EV_CTRL_END,
EV_CTRL_HOME,
EV_TAB_FORWARD,
EV_TAB_BACKWARD,
EV_NO_EVENT
};
static EVENT deadfieldevents[] = {
EV_HOME, EV_INSERT,
EV_NO_EVENT, /* end of list of ranges */
EV_TAB_FORWARD,
EV_TAB_BACKWARD,
EV_NO_EVENT
};
static EVENT setfield( VSCREEN *vptr, VFIELDEDIT *header, VFIELD *cur, ORD col )
/*********************************************/
{
register EVENT ev;
register VFIELD* prev;
if( cur != header->curfield ) {
prev = header->curfield;
if( prev ) {
/* change attribute on field being left */
uivtextput( vptr, prev->row, prev->col, header->exit,
header->buffer, prev->length );
}
header->prevfield = prev;
header->curfield = cur;
header->fieldpending = TRUE;
ev = EV_FIELD_CHANGE;
} else {
ev = EV_NO_EVENT;
}
if( cur != NULL ) {
vptr->row = cur->row;
vptr->col = cur->col + col;
}
return( ev );
}
static EVENT movecursor( VSCREEN *vptr, VFIELDEDIT *header, int row, int col )
/***********************************************/
{
register int cursor;
register int field = 0; // GCC wrongly thinks this might be uninited
register VFIELD* cur;
if( col < 0 ) {
col += vptr->area.width;
row -= 1;
} else if( col >= vptr->area.width ) {
col -= vptr->area.width;
row += 1;
}
row = max( 0, min( row, vptr->area.height - 1 ) );
cursor = row * vptr->area.width + col;
vptr->row = row;
vptr->col = col;
cur = header->fieldlist;
for( ; ; ) {
if( cur == NULL ) break;
field = cur->row * vptr->area.width + cur->col;
if( ( field <= cursor ) && ( field + cur->length > cursor ) ) break;
cur = cur->link;
}
return( setfield( vptr, header, cur, cursor - field ) );
}
static VFIELD *tabfield( VSCREEN *vptr, VFIELD *fieldlist, bool forward )
/*************************************************/
{
register VFIELD* chase;
register VFIELD* cur;
register int diff;
register int closest;
chase = fieldlist;
cur = chase;
closest = vptr->area.height * vptr->area.width;
while( chase != NULL ) {
if( forward ) {
diff = ( chase->row - vptr->row ) * vptr->area.width +
( chase->col - vptr->col );
} else {
diff = ( vptr->row - chase->row ) * vptr->area.width +
( vptr->col - chase->col );
}
if( diff <= 0 ) {
diff = diff + vptr->area.height * vptr->area.width;
}
if( diff < closest ) {
cur = chase;
closest = diff;
}
chase = chase->link;
}
return( cur );
}
EVENT global uivfieldedit( VSCREEN *vptr, VFIELDEDIT *header )
/************************************************************/
{
register EVENT ev;
register VFIELD* cur;
auto VBUFFER buffer;
auto SAREA area;
if( header->reset ) {
header->reset = FALSE;
header->prevfield = NULL;
header->curfield = NULL;
header->cursor = TRUE;
area.height = 1;
for( cur = header->fieldlist ; cur != NULL ; cur = cur->link ) {
area.row = cur->row;
area.col = cur->col;
area.width = cur->length;
uivattribute( vptr, area, header->exit );
}
}
if( header->cursor ) {
header->cursor = FALSE;
header->delpending = FALSE;
header->fieldpending = FALSE;
header->cancel = FALSE;
if( vptr->cursor == C_OFF ) {
vptr->cursor = C_NORMAL;
}
return( movecursor( vptr, header, vptr->row, vptr->col ) );
}
if( header->fieldpending ) {
header->update = TRUE;
if( header->cancel ) {
header->cancel = FALSE;
header->curfield = NULL;
setfield( vptr, header, header->prevfield, 0 );
}
header->fieldpending = FALSE;
}
cur = header->curfield;
if( header->update ) {
header->update = FALSE;
if( cur ) { /* this should always be non-NULL */
uipadblanks( header->buffer, cur->length );
if( header->delpending ) {
buffer.content = header->buffer;
buffer.length = cur->length;
buffer.index = vptr->col - cur->col;
uieditevent( EV_DELETE, &buffer );
header->dirty = TRUE;
header->delpending = FALSE;
}
uivtextput( vptr, cur->row, cur->col, header->enter,
header->buffer, cur->length );
}
}
if( header->oktomodify ) {
uipushlist( livefieldevents );
} else {
uipushlist( deadfieldevents );
}
ev = uivgetevent( vptr );
if( ev > EV_NO_EVENT ) {
if( uiintoplist( ev ) ) {
if( cur ) {
buffer.content = header->buffer;
buffer.length = cur->length;
buffer.index = vptr->col - cur->col;
buffer.insert = ( vptr->cursor == C_INSERT );
buffer.dirty = FALSE;
uieditevent( ev, &buffer );
header->dirty |= buffer.dirty;
}
switch( ev ) {
case EV_HOME:
if( cur != NULL ) break; /* home is within field */
/* WARNING: this case falls through to the next */
case EV_TAB_FORWARD:
case EV_TAB_BACKWARD:
cur = tabfield( vptr, header->fieldlist, ev == EV_TAB_FORWARD );
/* WARNING: the EV_HOME case falls through */
if( cur != NULL ) {
ev = setfield( vptr, header, cur, 0 );
cur = NULL; /* kludge - avoid calling movecursor */
}
break;
case EV_INSERT:
if( vptr->cursor == C_INSERT ) {
vptr->cursor = C_NORMAL ;
} else {
vptr->cursor = C_INSERT ;
}
break;
case EV_CURSOR_UP:
ev = movecursor( vptr, header, vptr->row - 1, vptr->col );
break;
case EV_CURSOR_DOWN:
ev = movecursor( vptr, header, vptr->row + 1, vptr->col );
break;
case EV_RUB_OUT:
header->delpending = TRUE;
/* WARNING: this case falls through to the next !!!! */
case EV_CURSOR_LEFT:
if( cur ) {
if( vptr->col > cur->col ) {
break; /* cursor movement within field */
}
}
ev = movecursor( vptr, header, vptr->row, vptr->col - 1 );
break;
case EV_CURSOR_RIGHT:
case ' ':
if( header->curfield ) {
if( vptr->col < cur->col + cur->length - 1 ) {
break; /* cursor movement within field */
}
}
ev = movecursor( vptr, header, vptr->row, vptr->col + 1 );
break;
}
if( ev != EV_FIELD_CHANGE ) {
if( cur ) {
ev = movecursor( vptr, header,
vptr->row, cur->col + buffer.index );
if( buffer.dirty && ( ev == EV_NO_EVENT ) ) {
uivtextput( vptr, cur->row, cur->col, header->enter,
header->buffer, cur->length );
}
} else {
ev = EV_NO_EVENT;
}
header->delpending = FALSE;
}
}
}
uipoplist();
return( ev );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?