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 + -
显示快捷键?