⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multiedit.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
		pText = (const char *) GUI_ALLOC_h2p(pObj->hText);
		pText += pObj->CursorPosByte;
		return _GetCharDistX(pObj, pText);
	}
	else
	{
		return 2;
	}
}

/*********************************************************************
*
*   	static code, buffer management
*
**********************************************************************
*/
/*********************************************************************
*
*   	_IncrementBuffer
*
* Increments the buffer size by AddBytes.
*/
static int _IncrementBuffer(MULTIEDIT_OBJ *pObj, unsigned AddBytes)
{
	WM_HMEM hNew;
	int NewSize;
	NewSize = pObj->BufferSize + AddBytes;
	hNew = GUI_ALLOC_Realloc(pObj->hText, NewSize);
	if (hNew)
	{
		if (!(pObj->hText))
		{
			char* pText;
			pText = (char *) GUI_ALLOC_h2p(hNew);
			*pText = 0;
		}
		pObj->BufferSize = NewSize;
		pObj->hText = hNew;
		return 1;
	}
	return 0;
}

/*********************************************************************
*
*   	_IsSpaceInBuffer
*
* Checks the available space in the buffer. If there is not enough
* space left this function attempts to get more.
*
* Returns:
*  1 = requested space is available
*  0 = failed to get enough space
*/
static int _IsSpaceInBuffer(MULTIEDIT_OBJ *pObj, int BytesNeeded)
{
	int NumBytes = 0;
	if (pObj->hText)
	{
		NumBytes = strlen((char *) GUI_ALLOC_h2p(pObj->hText));
	}
	BytesNeeded = (BytesNeeded + NumBytes + 1) - pObj->BufferSize;
	if (BytesNeeded > 0)
	{
		if (!_IncrementBuffer(pObj, BytesNeeded + MULTIEDIT_REALLOC_SIZE))
		{
			return 0;
		}
	}
	return 1;
}

/*********************************************************************
*
*   	_IsCharsAvailable
*
* Checks weither the maximum number of characters is reached or not.
*
* Returns:
*  1 = requested number of chars is available
*  0 = maximum number of chars have reached
*/
static int _IsCharsAvailable(MULTIEDIT_OBJ *pObj, int CharsNeeded)
{
	if ((CharsNeeded > 0) && (pObj->MaxNumChars > 0))
	{
		int NumChars = 0;
		if (pObj->hText)
		{
			NumChars = _GetNumChars(pObj);
		}
		if ((CharsNeeded + NumChars) > pObj->MaxNumChars)
		{
			return 0;
		}
	}
	return 1;
}

/*********************************************************************
*
*   	static code, string manipulation routines
*
**********************************************************************
*/
/*********************************************************************
*
*   	_DeleteChar
*
* Deletes a character at the current cursor position and moves
* all bytes after the cursor position.
*/
static void _DeleteChar(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ *pObj)
{
	if (pObj->hText)
	{
		unsigned CursorOffset;
		char* s;
		s = (char *) GUI_ALLOC_h2p(pObj->hText);
		CursorOffset = pObj->CursorPosByte;
		if (CursorOffset < strlen(s))
		{
			char *pCursor, *pLine, *pEndLine;
			int CursorLine, NumChars, NumBytes;
			pCursor = s + CursorOffset;
			CursorLine = pObj->CursorLine;
			pLine = _GetpLine(hObj, pObj, CursorLine);
			NumChars = _WrapGetNumCharsDisp(hObj, pObj, pLine);
			pEndLine = pLine + GUI_UC__NumChars2NumBytes(pLine, NumChars);
			pLine = pLine + _WrapGetNumBytesToNextLine(hObj, pObj, pLine);
			if (pCursor == pEndLine)
			{
				NumBytes = pLine - pEndLine;
			}
			else
			{
				NumBytes = GUI_UC_GetCharSize(pCursor);
			}
			NumChars = GUI_UC__NumBytes2NumChars(pCursor, NumBytes);
			strcpy(pCursor, pCursor + NumBytes);
			WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
			pObj->NumChars -= NumChars;
			_InvalidateNumLines(pObj);
			_InvalidateTextSizeX(pObj);
			_InvalidateCursorXY(pObj); /* Invalidate X/Y position */
			_ClearCache(pObj);
			pObj->CursorLine = _GetCursorLine(hObj, pObj, s, pObj->CursorPosChar);
		}
	}
}

/*********************************************************************
*
*   	_InsertChar
*
* Create space at the current cursor position and inserts a character.
*/
static int _InsertChar(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ *pObj, U16 Char)
{
	if (_IsCharsAvailable(pObj, 1))
	{
		int BytesNeeded;
		BytesNeeded = GUI_UC__CalcSizeOfChar(Char);
		if (_IsSpaceInBuffer(pObj, BytesNeeded))
		{
			int CursorOffset;
			char* pText;
			pText = (char *) GUI_ALLOC_h2p(pObj->hText);
			CursorOffset = pObj->CursorPosByte;
			pText += CursorOffset;
			memmove(pText + BytesNeeded, pText, strlen(pText) + 1);
			GUI_UC_Encode(pText, Char);
			WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
			pObj->NumChars += 1;
			_InvalidateNumLines(pObj);
			_InvalidateTextSizeX(pObj);
			_ClearCache(pObj);
			return 1;
		}
	}
	return 0;
}

/*********************************************************************
*
*   	static code
*
**********************************************************************
*/
/*********************************************************************
*
*   	_MULTIEDIT_Paint
*/
static void _MULTIEDIT_Paint(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ *pObj)
{
	int ScrollPosX, ScrollPosY, EffectSize, HBorder;
	int x, y, xOff, yOff, ColorIndex, FontSizeY;
	GUI_RECT r, rClip;
	const GUI_RECT *prOldClip;
	/* Init some values */
	GUI_SetFont(pObj->pFont);
	FontSizeY = GUI_GetFontDistY();
	ScrollPosX = pObj->ScrollStateH.v;
	ScrollPosY = pObj->ScrollStateV.v;
	EffectSize = pObj->Widget.pEffect->EffectSize;
	HBorder = pObj->HBorder;
	xOff = EffectSize + HBorder - ScrollPosX ;
	yOff = EffectSize - ScrollPosY * FontSizeY;
	ColorIndex = ((pObj->Flags & MULTIEDIT_SF_READONLY) ? 1 : 0);
	/* Set colors and draw the background */
	LCD_SetBkColor(pObj->aBkColor[ColorIndex]);
	LCD_SetColor(pObj->aColor[ColorIndex]);
	GUI_Clear();
	/* Draw the text if necessary */
	rClip.x0 = EffectSize + HBorder;
	rClip.y0 = EffectSize;
	rClip.x1 = WM_GetWindowSizeX(hObj) - EffectSize - HBorder - 1;
	rClip.y1 = WM_GetWindowSizeY(hObj) - EffectSize - 1;
	prOldClip = WM_SetUserClipRect(&rClip);
	if (pObj->hText)
	{
		const char* pText;
		int Line = 0;
		int xSize = _GetXSize(hObj, pObj);
		int NumVisLines = _GetNumVisLines(hObj, pObj);
		/* Get the text */
		pText = (const char *) GUI_ALLOC_h2p(pObj->hText);
		/* Set the rectangle for drawing */
		r.x0 = xOff;
		r.y0 = EffectSize;
		r.x1 = xSize + EffectSize + HBorder - 1;
		r.y1 = pObj->Widget.Win.Rect.y1 - pObj->Widget.Win.Rect.y0 + 1;
		/* Use cached position of first visible byte if possible */
		if (ScrollPosY >= pObj->CacheFirstVisibleLine)
		{
			if (pObj->CacheFirstVisibleByte)
			{
				pText += pObj->CacheFirstVisibleByte;
				Line = pObj->CacheFirstVisibleLine;
			}
		}
		/* Do the drawing of the text */
		do
		{
			/* Cache the position of the first visible byte and the depending line number */
			if (pObj->CacheFirstVisibleLine != ScrollPosY)
			{
				if (Line == ScrollPosY)
				{
					pObj->CacheFirstVisibleByte = pText - (const char *) GUI_ALLOC_h2p(pObj->hText);
					pObj->CacheFirstVisibleLine = ScrollPosY;
				}
			}
			/* Draw it */
			if ((Line >= ScrollPosY) && ((Line - ScrollPosY) <= NumVisLines))
			{
				_DispString(hObj, pObj, pText, &r);
				r.y0 += FontSizeY;  /* Next line */
			}
			pText += _WrapGetNumBytesToNextLine(hObj, pObj, pText);
			Line++;
		}
		while (GUI_UC_GetCharCode(pText) && ((Line - ScrollPosY) <= NumVisLines));
	}
	/* Draw cursor if necessary */
	if (WM_HasFocus(hObj))
	{
		_GetCursorXY(hObj, pObj, &x, &y);
		r.x0 = x + xOff;
		r.y0 = y + yOff;
		r.x1 = r.x0 + _GetCursorSizeX(hObj, pObj) - 1;
		r.y1 = r.y0 + FontSizeY - 1;
		GUI_InvertRect(r.x0, r.y0, r.x1, r.y1);
	}
	WM_SetUserClipRect(prOldClip);
	/* Draw the 3D effect (if configured) */
	WIDGET__EFFECT_DrawDown(&pObj->Widget);
}

/*********************************************************************
*
*   	_OnTouch
*/
static void _OnTouch(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ *pObj, WM_MESSAGE *pMsg)
{
	int Notification;
	const GUI_PID_STATE* pState = (const GUI_PID_STATE *) pMsg->Data.p;
	if (pMsg->Data.p)
	{
		/* Something happened in our area (pressed or released) */
		if (pState->Pressed)
		{
			int Effect, xPos, yPos;
			Effect = pObj->Widget.pEffect->EffectSize;
			xPos = pState->x + pObj->ScrollStateH.v - Effect - pObj->HBorder;
			yPos = pState->y + pObj->ScrollStateV.v * GUI_GetYDistOfFont(pObj->pFont) - Effect;
			_SetCursorXY(hObj, pObj, xPos, yPos);
			_Invalidate(hObj);
			Notification = WM_NOTIFICATION_CLICKED;
		}
		else
		{
			Notification = WM_NOTIFICATION_RELEASED;
		}
	}
	else
	{
		Notification = WM_NOTIFICATION_MOVED_OUT;
	}
	WM_NotifyParent(hObj, Notification);
}

/*********************************************************************
*
*   	_AddKey
*
* Returns: 1 if Key has been consumed
*   	   0 else 
*/
static int _AddKey(MULTIEDIT_HANDLE hObj, U16 Key)
{
	int r = 0;  			 /* Key has not been consumed */
	MULTIEDIT_OBJ* pObj;
	pObj = MULTIEDIT_H2P(hObj);
	switch (Key)
	{
		case GUI_KEY_UP:
			_MoveCursorUp(hObj, pObj);
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_DOWN:
			_MoveCursorDown(hObj, pObj);
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_RIGHT:
			_SetCursorPos(hObj, pObj, pObj->CursorPosChar + 1);
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_LEFT:
			_SetCursorPos(hObj, pObj, pObj->CursorPosChar - 1);
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_END:
			_MoveCursor2LineEnd(hObj, pObj);
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_HOME:
			_MoveCursor2LinePos1(hObj, pObj);
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_BACKSPACE:
			if (!(pObj->Flags & MULTIEDIT_SF_READONLY))
			{
				if (pObj->CursorPosChar > pObj->NumCharsPrompt)
				{
					_SetCursorPos(hObj, pObj, pObj->CursorPosChar - 1);
					_DeleteChar(hObj, pObj);
				}
				r = 1;  			 /* Key has been consumed */
			}
			break;
		case GUI_KEY_DELETE:
			if (!(pObj->Flags & MULTIEDIT_SF_READONLY))
			{
				_DeleteChar(hObj, pObj);
				r = 1;  			 /* Key has been consumed */
			}
			break;
		case GUI_KEY_INSERT:
			if (!(pObj->Flags & MULTIEDIT_CF_INSERT))
			{
				pObj->Flags |= MULTIEDIT_CF_INSERT;
			}
			else
			{
				pObj->Flags &= ~MULTIEDIT_CF_INSERT;
			}
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_ENTER:
			if (pObj->Flags & MULTIEDIT_SF_READONLY)
			{
				_MoveCursor2NextLine(hObj, pObj);
			}
			else
			{
				if (_InsertChar(hObj, pObj, (U8) ('\n')))
				{
					if (pObj->Flags & MULTIEDIT_SF_PASSWORD)
					{
						_SetCursorPos(hObj, pObj, pObj->CursorPosChar + 1);
					}
					else
					{
						_MoveCursor2NextLine(hObj, pObj);
					}
				}
			}
			r = 1;  			 /* Key has been consumed */
			break;
		case GUI_KEY_ESCAPE:
			break;
		default:
			if (!(pObj->Flags & MULTIEDIT_SF_READONLY) && (Key >= 0x20))
			{
				if (_IsOverwriteAtThisChar(hObj, pObj))
				{
					_DeleteChar(hObj, pObj);
				}
				if (_InsertChar(hObj, pObj, Key))
				{
					_SetCursorPos(hObj, pObj, pObj->CursorPosChar + 1);
				}
				r = 1;  			 /* Key has been consumed */
			}
	}
	_InvalidateTextArea(hObj);
	return r;
}

/*********************************************************************
*
*   	_MULTIEDIT_Callback
*/
static void _MULTIEDIT_Callback(WM_MESSAGE *pMsg)
{
	MULTIEDIT_HANDLE hObj;
	MULTIEDIT_OBJ* pObj;
	WM_SCROLL_STATE ScrollState;
	hObj = pMsg->hWin;
	/* Let widget handle the standard messages */
	if (WIDGET_HandleActive(hObj, pMsg) == 0)
	{
		return;
	}
	pObj = MULTIEDIT_H2P(hObj);
	switch (pMsg->MsgId)
	{
		case WM_NOTIFY_CLIENTCHANGE:
			_InvalidateCursorXY(pObj);
			_InvalidateNumLines(pObj);
			_InvalidateTextSizeX(pObj);
			_ClearCache(pObj);
			_CalcScrollParas(hObj);
			break;
		case WM_SIZE:
			_InvalidateCursorXY(pObj);
			_InvalidateNumLines(pObj);
			_InvalidateTextSizeX(pObj);
			_ClearCache(pObj);
			_Invalidate(hObj);
			break;
		case WM_NOTIFY_PARENT:
			switch (pMsg->Data.v)
			{
				case WM_NOTIFICATION_VALUE_CHANGED:
					if (pMsg->hWinSrc == WM_GetScrollbarV(hObj))
					{
						WM_GetScrollState(pMsg->hWinSrc, &ScrollState);
						pObj->ScrollStateV.v = ScrollState.v;
						WM_InvalidateWindow(hObj);
						WM_NotifyParent(hObj, WM_NOTIFICATION_SCROLL_CHANGED);
					}
					else if (pMsg->hWinSrc == WM_GetScrollbarH(hObj))
					{
						WM_GetScrollState(pMsg->hWinSrc, &ScrollState);
						pObj->ScrollStateH.v = ScrollState.v;
						WM_InvalidateWindow(hObj);
						WM_NotifyParent(hObj, WM_NOTIFICATION_SCROLL_CHANGED);
					}
					break;
				case WM_NOTIFICATION_SCROLLBAR_ADDED:
					_SetScrollState(hObj);
					break;
			}
			break;
		case WM_PAINT:
			_MULTIEDIT_Paint(hObj, pObj);
			return;
		case WM_TOUCH:
			_OnTouch(hObj, pObj, pMsg);
			break;
		case WM_DELETE:
			GUI_ALLOC_FreePtr(&pObj->hText);
			break;
		case WM_KEY:
			if (((const WM_KEY_INFO *) (pMsg->Data.p))->PressedCnt > 0)
			{
				int Key = ((const WM_KEY_INFO *) (pMsg->Data.p))->Key;
				/* Leave code for test purpose
				switch (Key) {
				case '1': Key = GUI_KEY_LEFT;  break;
				case '2': Key = GUI_KEY_UP;    break;
				case '3': Key = GUI_KEY_RIGHT; break;
				case '4': Key = GUI_KEY_DOWN;  break;
				}
				*/
				if (_AddKey(hObj, Key))
				{
					return;
				}
			}
			else
			{
				if (!(pObj->Flags & MULTIEDIT_SF_READONLY))
				{
					return; 			   /* Key release is consumed (not sent to parent) */
				}
			}
	}
	WM_DefaultProc(pMsg);
}

/*********************************************************************
*
*   	Exported routines:  Create
*
**********************************************************************
*/

/* Note: the parameters to a create function may vary.
		 Some widgets may have multiple create functions */

⌨️ 快捷键说明

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