asix_ed.c
来自「一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上」· C语言 代码 · 共 1,876 行 · 第 1/4 页
C
1,876 行
STATUS ed_enable(void *ctrl_str, U8 enable)
{
struct ed_ctrl *edctrl;
ASIX_WINDOW *wndptr;
U32 hGC;
edctrl = (struct ed_ctrl*) ctrl_str;
if( edctrl == NULL )
return ASIX_ERROR;
wndptr = (ASIX_WINDOW *)edctrl->windowid;
hGC = GetGC();
if( enable )
{
if( !( wndptr->status & WST_ENABLE ) )
{
if( ActiveAreaSuspend( edctrl->editorid, AREA_REENABLE ) != PPSM_OK )
return ASIX_ERROR;
ClearRec( hGC, EDITOR_BACKGROUND_COLOR, edctrl->x, edctrl->y, edctrl->width, edctrl->height, GPC_REPLACE_STYLE );
if( !( edctrl->style & ES_NOBORDER ) )
DrawRec( hGC, EDITOR_FRAME_COLOR, edctrl->x, edctrl->y, edctrl->x+edctrl->width-1, edctrl->y+edctrl->height-1, GPC_SOLID_LINE, GPC_REPLACE_STYLE );
UpdateInputArea( edctrl, edctrl->curPage, 0 );
}
}
else
{
if( wndptr->status & WST_ENABLE )
{
//suspend the button
if( ActiveAreaSuspend(edctrl->editorid, AREA_SUSPEND ) != PPSM_OK )
return ASIX_ERROR;
ClearRec( hGC, EDITOR_DISABLE_COLOR, edctrl->x, edctrl->y, edctrl->width, edctrl->height, GPC_XOR_STYLE );
if( !( edctrl->style & ES_NOBORDER ) )
DrawRec( hGC, EDITOR_FRAME_COLOR, edctrl->x, edctrl->y, edctrl->x+edctrl->width-1, edctrl->y+edctrl->height-1, GPC_SOLID_LINE, GPC_REPLACE_STYLE );
}
}
return ASIX_OK;
}
STATUS InitialMatrix( struct ed_ctrl *edctrl )
{
struct char_matrix *pmatrix;
U16 lineStrLen = 0;
// U16 offset;
U16 i, j;
struct char_pos *vector;
S8 *p;
if( edctrl->pmatrix == NULL ) // 初始化显示矩阵
{
pmatrix = (struct char_matrix *)Lcalloc( sizeof(struct char_matrix) * edctrl->maxLine );
if( pmatrix == NULL )
return ASIX_ERROR;
asix_ed_memdbgprintf( "asix_ed appeal mem for its matrix" );
vector = (struct char_pos *)Lmalloc( sizeof( struct char_pos ) * edctrl->pageLine * (edctrl->pageColumn +1) );
if( vector == NULL )
{
Lfree( pmatrix );
asix_ed_memdbgprintf( "asix_ed free mem of its vector" );
return ASIX_ERROR;
}
asix_ed_memdbgprintf( "asix_ed appeal mem for its vector" );
edctrl->pmatrix = pmatrix;
edctrl->vector = vector;
}
else
{
pmatrix = edctrl->pmatrix;
vector = edctrl->vector;
}
for( i = 0; i < edctrl->pageLine; i++ )
pmatrix[i].vector = vector + (edctrl->pageColumn +1) * i;
if( edctrl->style & ES_MULTILINE ) // 多行编辑方式
{
// 填充有效页(有字符且当前显示)的矩阵结构
pmatrix[0].lineHead = edctrl->pbuf;
pmatrix[0].x = edctrl->x +1;
pmatrix[0].y = edctrl->y +1;
FillVector( edctrl, pmatrix[0].lineHead, 0, &lineStrLen );
i = 1;
p = pmatrix[0].lineHead + lineStrLen;
while( i < edctrl->pageLine && *p != '\0' )
{
pmatrix[i].x = edctrl->x +1;
pmatrix[i].y = pmatrix[i-1].y + edctrl->lineHeight;
pmatrix[i].lineHead = p;
FillVector( edctrl, pmatrix[i].lineHead, i, &lineStrLen );
p = pmatrix[i].lineHead + lineStrLen;
i++;
}
edctrl->curPage = 0;
edctrl->curLine = i - 1;
edctrl->curColumn = edctrl->pmatrix[edctrl->curLine].len;
for( j = i; j < edctrl->pageLine; j++ )
{
pmatrix[j].x = edctrl->x +1;
pmatrix[j].y = pmatrix[j-1].y + edctrl->lineHeight;
pmatrix[j].lineHead = NULL;
}
while( *p != '\0' )
{
pmatrix[i].lineHead = p;
FillVector( edctrl, pmatrix[i].lineHead, i, &lineStrLen );
p = pmatrix[i].lineHead + lineStrLen;
i++;
}
edctrl->maxPage = i - edctrl->pageLine;
// 设置光标初始位置
pmatrix = &pmatrix[ edctrl->curLine ];
edctrl->curCursorPos = pmatrix->lineHead + pmatrix->vector[pmatrix->len].index;
}
else // 单行编辑方式
{
pmatrix->x = edctrl->x +1;
pmatrix->y = edctrl->y +1;
pmatrix->lineHead = edctrl->pbuf;
FillVector( edctrl, pmatrix->lineHead, 0, &lineStrLen );
edctrl->curPage = 0;
edctrl->curLine = 0;
edctrl->curColumn = pmatrix->len;
// edctrl->endLine = 0;
edctrl->curCursorPos = pmatrix->lineHead + pmatrix->vector[pmatrix->len].index;
}
return ASIX_OK;
}
STATUS OrgnizeMatrix( struct ed_ctrl *edctrl, U16 startLine, U16 startColumn )
{
struct char_matrix *pmatrix;
U16 lineStrLen = 0;
// U16 offset;
U16 i, y;
U8 *p;
if( edctrl->style & ES_MULTILINE ) // 多行编辑方式
{
i = startLine;
p = edctrl->pmatrix[i].lineHead;
y = edctrl->pmatrix[i].y;
while( i < edctrl->curPage + edctrl->pageLine )
{
pmatrix = &edctrl->pmatrix[i];
pmatrix->y = y;
y += edctrl->lineHeight;
if( p != NULL )
{
pmatrix->lineHead = p;
FillVector( edctrl, pmatrix->lineHead, i, &lineStrLen );
if( *p == '\0' )
{
p = NULL;
pmatrix->lineHead = NULL;
}
else
p = pmatrix->lineHead + lineStrLen;
}
else
pmatrix->lineHead = NULL;
i++;
}
edctrl->maxPage = edctrl->curPage;
if( pmatrix->lineHead != NULL && p != NULL )
{
while( *p != '\0' )
{
FillVector( edctrl, p, i, &lineStrLen );
p += lineStrLen;
edctrl->maxPage++;
}
}
SetScrollRange( edctrl->sbid, 0, edctrl->maxPage );
pmatrix = &edctrl->pmatrix[edctrl->curPage];
if( pmatrix->lineHead == NULL )
{
pmatrix->len = 0;
pmatrix->lineHead = edctrl->pbuf;
FillVector( edctrl, pmatrix->lineHead, edctrl->curPage, &lineStrLen );
}
}
else // 单行编辑方式
{
pmatrix = edctrl->pmatrix;
FillVector( edctrl, pmatrix->lineHead, 0, &lineStrLen );
}
return ASIX_OK;
}
void UpdateInputArea( struct ed_ctrl *edctrl, U16 startLine, U16 startColumn )
{
U32 hGC;
S8 *lineStr;
U16 topx, topy, linex, liney, dispLen;
struct char_matrix *pmatrix;
U16 i;
hGC = GetGC();
// GroupOn( hGC );
if( edctrl->windowid == GetFocus() )
StopCursor( hGC );
for( i = startLine; i < edctrl->curPage +edctrl->pageLine; i++ )
{
pmatrix = &edctrl->pmatrix[i];
lineStr = pmatrix->lineHead;
linex = pmatrix->x;
liney = pmatrix->y;
if( lineStr != NULL && pmatrix->vector != NULL )
dispLen = pmatrix->vector[pmatrix->len].index;
else
dispLen = 0;
topx = pmatrix->vector[0].x;
topy = liney + ( edctrl->lineHeight - ENGLISH_CHAR_HEIGHT )/2;
ClearRec( hGC, EDITOR_BACKGROUND_COLOR, linex, liney, edctrl->width -2, edctrl->lineHeight, GPC_REPLACE_STYLE );
//TextOut( hGC, lineStr, topx, topy, 0, EDITOR_TEXT_COLOR, GPC_REPLACE_STYLE );
if( lineStr != NULL )
TextOutEx( hGC, lineStr, topx, topy, 0, EDITOR_TEXT_COLOR, GPC_REPLACE_STYLE, dispLen, GPC_TRANSPARENT_STYLE, EDITOR_BACKGROUND_COLOR );
}
if( edctrl->windowid == GetFocus() )
{
//AdjustCursorDisp( hGC );
topy = edctrl->pmatrix[edctrl->curLine].y + ( edctrl->lineHeight - ENGLISH_CHAR_HEIGHT )/2;
SetCursorPosition( hGC, edctrl->pmatrix[edctrl->curLine].vector[edctrl->curColumn].x, topy );
StartCursor( hGC );
}
// GroupOff( hGC, edctrl->x, edctrl->y, edctrl->x + edctrl->width -1, edctrl->y + edctrl->height -1 );
return;
}
STATUS FillVector( struct ed_ctrl *edctrl, S8 *str, U16 line, U16 *strLen )
{
U8 i, j;
U16 len = 0, w = 0, dif;
struct char_pos *vector = edctrl->pmatrix[line].vector;
if( vector == NULL )
{
vector = (struct char_pos *)Lmalloc( sizeof( struct char_pos ) * (edctrl->pageColumn +1) );
if( vector == NULL )
return ASIX_ERROR;
}
for( i = 0, j = 0; ; i++, j++ ) // left align text style
{
vector[j].index = i;
vector[j].x = w;
if( str[i] == '\0' ) // if click tail blank, cursor will go to string end.
break;
if( str[i] & 0x80 ) // Chinese char fill two index
{
w += CHINESE_CHAR_WIDTH;
if( w > edctrl->width -4 )
{
w -= CHINESE_CHAR_WIDTH;
break;
}
i++;
len += 2;
}
else // English char fill one index
{
if( ( edctrl->style & ES_MULTILINE ) && ( str[i] == '\n' || str[i] == '\r' ) )
{
len++;
break;
}
w += ENGLISH_CHAR_WIDTH;
if( w > edctrl->width -4 )
{
w -= ENGLISH_CHAR_WIDTH;
break;
}
len++;
}
}
*strLen = len;
edctrl->pmatrix[line].len = j;
edctrl->pmatrix[line].w = w;
switch( edctrl->style & ES_GROUP2 )
{
case ES_LEFT:
dif = edctrl->x +2;
break;
case ES_CENTER:
dif = edctrl->x + ( edctrl->width - w -1 )/2 ;
break;
case ES_RIGHT:
dif = edctrl->x + edctrl->width - w -2;
break;
default:
return ASIX_ERROR;
}
for( i = 0; i <= j; i++ )
vector[i].x += dif;
if( edctrl->pmatrix[line].vector == NULL )
Lfree( vector );
return ASIX_OK;
}
S8 *InsertChar( S8 *str, S8 *pos, U16 v, U32 *strLen, U32 bufSize )
{
U8 vLen, *temp;
vLen = ( v & 0xff00 )? 2 : 1;
if( *strLen >= bufSize - vLen ) // buffer full
return NULL;
temp = (S8 *)Lcalloc( str + *strLen - pos + 1 );
if( temp == NULL )
return NULL;
asix_ed_memdbgprintf( "asix_ed appeal mem for string" );
strcpy( temp, pos );
if( vLen == 2 ) // insert char is Chinese char
{
Word2Bytes( (U8 *)pos, v );
pos += 2;
}
else // insert char is English char
{
*pos = (S8) (v & 0x00ff);
pos++;
}
strcpy( pos, temp );
Lfree( temp );
asix_ed_memdbgprintf( "asix_ed free mem of string" );
(*strLen) += vLen;
return pos;
}
void LocateCursorPos( struct ed_ctrl *edctrl )
{
U16 len, step, stepL, stepR;
U16 pos, x, i;
if( edctrl->style & ES_MULTILINE )
{
i = edctrl->curPage;
while( i < edctrl->curPage + edctrl->pageLine && edctrl->pmatrix[i].y < edctrl->peny )
{
if( edctrl->pmatrix[i].lineHead == NULL )
{
edctrl->curLine = i -1;
edctrl->curColumn = edctrl->pmatrix[edctrl->curLine].len;
return;
}
i++;
}
if( i == edctrl->curPage )
i++;
edctrl->curLine = i - 1;
len = edctrl->pmatrix[edctrl->curLine].len;
}
else
{
edctrl->curLine = 0;
len = edctrl->pmatrix[0].len;
}
// 二分查找
step = len +1;
pos = step/2;
stepL = step/2;
stepR = step - stepL -1;
while( step > 1 )
{
x = edctrl->pmatrix[edctrl->curLine].vector[pos].x;
if( edctrl->penx == x ) // 找到
break;
else
if( edctrl->penx > x ) // 查找右区间
{
if( stepR == 0 )
break;
step = stepR;
stepL = step/2;
stepR = step - stepL -1;
pos += ( stepL +1 );
}
else // 查找左区间
{
if( stepL == 0 )
break;
step = stepL;
stepL = step/2;
stepR = step - stepL -1;
pos -= ( stepR +1 );
}
}
if( step != 1 )
edctrl->curColumn = pos;
else
{
if( pos == 0 )
edctrl->curColumn = pos;
else
if( edctrl->penx < edctrl->pmatrix[edctrl->curLine].vector[pos].x )
edctrl->curColumn = pos -1;
else
edctrl->curColumn = pos;
}
return;
}
STATUS SingleEdMsgProc( U16 asix_msg, struct ed_ctrl *edctrl, void *data, U16 wparam, void *reserved )
{
U32 hGC;
MSG ed_msg;
S8 *newPos, *curLineHead;
U16 offset, cLen, width;
U8 *p;
U16 dispx, dispy;
struct char_matrix *pmatrix;
U16 charHeight;
U16 i;
hGC = GetGC();
memset( &ed_msg, 0x0, sizeof(MSG) );
ed_msg.messageType = ASIX_MESSAGE;
pmatrix = &edctrl->pmatrix[0];
switch( asix_msg )
{
case WM_CHAR:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?