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

📄 multiedit.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
*********************************************************************************************************
*   											 uC/GUI
*   					 Universal graphic software for embedded applications
*
*   					(c) Copyright 2002, Micrium Inc., Weston, FL
*   					(c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
*   		   礐/GUI is protected by international copyright laws. Knowledge of the
*   		   source code may not be used to write a similar product. This file may
*   		   only be used in accordance with a license and should not be redistributed
*   		   in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File		: MULTIEDIT.c
Purpose 	: Implementation of MULTIEDIT widget
---------------------------END-OF-HEADER------------------------------
*/

#include <stdlib.h>
#include <string.h>
#include "MULTIEDIT.h"
#include "WIDGET.h"
#include "WM_Intern.h"

#if GUI_WINSUPPORT

/*********************************************************************
*
*   	Private config defaults
*
**********************************************************************
*/

/* Define default fonts */
#ifndef MULTIEDIT_FONT_DEFAULT
#define MULTIEDIT_FONT_DEFAULT &GUI_Font13_1
#endif

/* Define colors */
#ifndef MULTIEDIT_BKCOLOR0_DEFAULT
#define MULTIEDIT_BKCOLOR0_DEFAULT   GUI_WHITE
#endif

#ifndef MULTIEDIT_BKCOLOR1_DEFAULT
#define MULTIEDIT_BKCOLOR1_DEFAULT   0xC0C0C0
#endif

#ifndef MULTIEDIT_TEXTCOLOR0_DEFAULT
#define MULTIEDIT_TEXTCOLOR0_DEFAULT GUI_BLACK
#endif

#ifndef MULTIEDIT_TEXTCOLOR1_DEFAULT
#define MULTIEDIT_TEXTCOLOR1_DEFAULT GUI_BLACK
#endif

/* Define character for password mode */
#define MULTIEDIT_PASSWORD_CHAR   '*'

/*********************************************************************
*
*   	Object definition
*
**********************************************************************
*/

#define NUM_DISP_MODES 2

#define INVALID_NUMCHARS (1 << 0)
#define INVALID_NUMLINES (1 << 1)
#define INVALID_TEXTSIZE (1 << 2)
#define INVALID_CURSORXY (1 << 3)
#define INVALID_LINEPOSB (1 << 4)

typedef struct
{
	WIDGET						Widget;
	GUI_COLOR					aBkColor[NUM_DISP_MODES];
	GUI_COLOR					aColor[NUM_DISP_MODES];
	WM_HMEM						hText;
	U16							MaxNumChars;		 /* Maximum number of characters including the prompt */			
	U16							NumChars;   		 /* Number of characters (text and prompt) in object */ 				   
	U16							NumCharsPrompt; 	 /* Number of prompt characters */
	U16							NumLines;   		 /* Number of text lines needed to show all data */
	U16							TextSizeX;  		 /* Size in X of text depending of wrapping mode */
	U16							BufferSize;
	U16							CursorLine; 		 /* Number of current cursor line */
	U16							CursorPosChar;  	 /* Character offset number of cursor */
	U16							CursorPosByte;  	 /* Byte offset number of cursor */
	U16							CursorPosX; 		 /* Cursor position in X */
	U16							CursorPosY; 		 /* Cursor position in Y */
	U16							CacheLinePosByte;    /*  */
	U16							CacheLineNumber;	 /*  */
	U16							CacheFirstVisibleLine;
	U16							CacheFirstVisibleByte;
	WM_SCROLL_STATE				ScrollStateV;
	WM_SCROLL_STATE				ScrollStateH;
	const GUI_FONT GUI_UNI_PTR	*pFont;
	U8							Flags;
	U8							InvalidFlags;   	  /* Flags to save validation status */
	U8							EditMode;
	U8							HBorder;
	GUI_WRAPMODE				WrapMode;
#if GUI_DEBUG_LEVEL >1
	int							DebugId;
#endif
} MULTIEDIT_OBJ;

/*********************************************************************
*
*   	Static data
*
**********************************************************************
*/

static GUI_COLOR _aDefaultBkColor[2] = {
MULTIEDIT_BKCOLOR0_DEFAULT,
MULTIEDIT_BKCOLOR1_DEFAULT,
};

static GUI_COLOR _aDefaultColor[2] = {
MULTIEDIT_TEXTCOLOR0_DEFAULT,
MULTIEDIT_TEXTCOLOR1_DEFAULT,
};

static const GUI_FONT GUI_UNI_PTR * _pDefaultFont = MULTIEDIT_FONT_DEFAULT;

/*********************************************************************
*
*   	Macros for internal use
*
**********************************************************************
*/

#define MULTIEDIT_ID 0x8793   /* Magic numer, should be unique if possible */

#define MULTIEDIT_H2P(h) (MULTIEDIT_OBJ*) WM_H2P(h)

#define MULTIEDIT_REALLOC_SIZE  16

#if GUI_DEBUG_LEVEL > 1
#define MULTIEDIT_ASSERT_IS_VALID_PTR(p) DEBUG_ERROROUT_IF(p->DebugId != MULTIEDIT_ID, "MULTIEDIT.c: Wrong handle type or Object not init'ed")
#define MULTIEDIT_INIT_ID(p)   p->DebugId = MULTIEDIT_ID
#define MULTIEDIT_DEINIT_ID(p) p->DebugId = MULTIEDIT_ID+1
#else
#define MULTIEDIT_ASSERT_IS_VALID_PTR(p)
#define MULTIEDIT_INIT_ID(p)
#define MULTIEDIT_DEINIT_ID(p)
#endif

/*********************************************************************
*
*   	static code, helper functions
*
**********************************************************************
*/

/*********************************************************************
*
*   	_InvalidateNumChars
*
* Invalidates the number of characters including the prompt
*/
static void _InvalidateNumChars(MULTIEDIT_OBJ *pObj)
{
	pObj->InvalidFlags |= INVALID_NUMCHARS;
}

/*********************************************************************
*
*   	_GetNumChars
*
* Calculates (if needed) and returns the number of characters including the prompt
*/
static int _GetNumChars(MULTIEDIT_OBJ *pObj)
{
	if (pObj->InvalidFlags & INVALID_NUMCHARS)
	{
		char * pText;
		pText = (char *) GUI_ALLOC_h2p(pObj->hText);
		pObj->NumChars = GUI__GetNumChars(pText);
		pObj->InvalidFlags &= ~INVALID_NUMCHARS;
	}
	return pObj->NumChars;
}

/*********************************************************************
*
*   	_GetXSize
*
* Returns the x size for displaying text.
*/
static int _GetXSize(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ *pObj)
{
	GUI_RECT Rect;
	WM_GetInsideRectExScrollbar(hObj, &Rect);
	return Rect.x1 - Rect.x0 - (pObj->HBorder * 2) - 1;
}

/*********************************************************************
*
*   	_GetNumCharsInPrompt
*/
static int _GetNumCharsInPrompt(const MULTIEDIT_OBJ *pObj, const char GUI_UNI_PTR *pText)
{
	char *pString, *pEndPrompt;
	int r = 0;
	pString = (char *) GUI_ALLOC_h2p(pObj->hText);
	pEndPrompt = pString + GUI_UC__NumChars2NumBytes(pString, pObj->NumCharsPrompt);
	if (pText < pEndPrompt)
	{
		r = GUI_UC__NumBytes2NumChars(pText, pEndPrompt - pText);
	}
	return r;
}

/*********************************************************************
*
*   	_NumChars2XSize
*/
static int _NumChars2XSize(const char GUI_UNI_PTR *pText, int NumChars)
{
	int xSize = 0;
	U16 Char;
	while (NumChars--)
	{
		Char = GUI_UC__GetCharCodeInc(&pText);
		xSize += GUI_GetCharDistX(Char);
	}
	return xSize;
}

/*********************************************************************
*
*   	_WrapGetNumCharsDisp
*/
static int _WrapGetNumCharsDisp(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ *pObj, const char GUI_UNI_PTR *pText)
{
	int xSize, r;
	xSize = _GetXSize(hObj, pObj);
	if (pObj->Flags & MULTIEDIT_SF_PASSWORD)
	{
		int NumCharsPrompt;
		NumCharsPrompt = _GetNumCharsInPrompt(pObj, pText);
		r = GUI__WrapGetNumCharsDisp(pText, xSize, pObj->WrapMode);
		if (r >= NumCharsPrompt)
		{
			int x;
			switch (pObj->WrapMode)
			{
				case GUI_WRAPMODE_NONE:
					r = GUI__GetNumChars(pText);
					break;
				default:
					r = NumCharsPrompt;
					x = _NumChars2XSize(pText, NumCharsPrompt);
					pText += GUI_UC__NumChars2NumBytes(pText, NumCharsPrompt);
					while (GUI_UC__GetCharCodeInc(&pText) != 0)
					{
						x += GUI_GetCharDistX(MULTIEDIT_PASSWORD_CHAR);
						if (r && (x > xSize))
						{
							break;
						}
						r++;
					}
					break;
			}
		}
	}
	else
	{
		r = GUI__WrapGetNumCharsDisp(pText, xSize, pObj->WrapMode);
	}
	return r;
}

/*********************************************************************
*
*   	_WrapGetNumBytesToNextLine
*/
static int _WrapGetNumBytesToNextLine(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ *pObj, const char *pText)
{
	int xSize, r;
	xSize = _GetXSize(hObj, pObj);
	if (pObj->Flags & MULTIEDIT_SF_PASSWORD)
	{
		int NumChars, NumCharsPrompt;
		NumCharsPrompt = _GetNumCharsInPrompt(pObj, pText);
		NumChars = _WrapGetNumCharsDisp(hObj, pObj, pText);
		r = GUI_UC__NumChars2NumBytes(pText, NumChars);
		if (NumChars < NumCharsPrompt)
		{
			if (*(pText + r) == '\n')
			{
				r++;
			}
		}
	}
	else
	{
		r = GUI__WrapGetNumBytesToNextLine(pText, xSize, pObj->WrapMode);
	}
	return r;
}

/*********************************************************************
*
*   	_GetCharDistX
*/
static int _GetCharDistX(const MULTIEDIT_OBJ *pObj, const char *pText)
{
	int r;
	if ((pObj->Flags & MULTIEDIT_SF_PASSWORD) && (_GetNumCharsInPrompt(pObj, pText) == 0))
	{
		r = GUI_GetCharDistX(MULTIEDIT_PASSWORD_CHAR);
	}
	else
	{
		U16 c;
		c = GUI_UC_GetCharCode(pText);
		r = GUI_GetCharDistX(c);
	}
	return r;
}

/*********************************************************************
*
*   	_DispString
*/
static void _DispString(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ *pObj, const char *pText, GUI_RECT *pRect)
{
	int NumCharsDisp;
	NumCharsDisp = _WrapGetNumCharsDisp(hObj, pObj, pText);
	if (pObj->Flags & MULTIEDIT_SF_PASSWORD)
	{
		int x, NumCharsPrompt, NumCharsLeft = 0;
		NumCharsPrompt = _GetNumCharsInPrompt(pObj, pText);
		if (NumCharsDisp < NumCharsPrompt)
		{
			NumCharsPrompt = NumCharsDisp;
		}
		else
		{
			NumCharsLeft = NumCharsDisp - NumCharsPrompt;
		}
		GUI_DispStringInRectMax(pText, pRect, GUI_TA_LEFT, NumCharsPrompt);
		x = pRect->x0 + _NumChars2XSize(pText, NumCharsPrompt);
		if (NumCharsLeft)
		{
			GUI_DispCharAt(MULTIEDIT_PASSWORD_CHAR, x, pRect->y0);
			GUI_DispChars(MULTIEDIT_PASSWORD_CHAR, NumCharsLeft - 1);
		}
	}
	else
	{
		GUI_DispStringInRectMax(pText, pRect, GUI_TA_LEFT, NumCharsDisp);
	}
}

/*********************************************************************
*
*   	static code, cursor routines
*
**********************************************************************
*/
/*********************************************************************
*
*   	_GetpLine
*
* Returns a pointer to the beginning of the line with the
* given line number.
*/
static char * _GetpLine(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ *pObj, unsigned LineNumber)
{
	char * pText, *pLine;
	pText = (char *) GUI_ALLOC_h2p(pObj->hText);
	if ((unsigned) pObj->CacheLineNumber != LineNumber)
	{
		if (LineNumber > (unsigned) pObj->CacheLineNumber)
		{
			/* If new line number > cache we can start with old pointer */
			int OldNumber = pObj->CacheLineNumber;
			pLine = pText + pObj->CacheLinePosByte;
			pObj->CacheLineNumber = LineNumber;
			LineNumber -= OldNumber;
		}
		else
		{
			/* If new line number < cache we need to start with first byte */
			pLine = pText;
			pObj->CacheLineNumber = LineNumber;
		}
		while (LineNumber--)
		{
			pLine += _WrapGetNumBytesToNextLine(hObj, pObj, pLine);
		}
		pObj->CacheLinePosByte = pLine - pText;
	}
	return pText + pObj->CacheLinePosByte;
}

/*********************************************************************
*
*   	_ClearCache
*
* Clears the cached position of the linenumber and the first byte
* of the line which holds the cursor.
*/
static void _ClearCache(MULTIEDIT_OBJ *pObj)
{
	pObj->CacheLineNumber = 0;
	pObj->CacheLinePosByte = 0;
	pObj->CacheFirstVisibleByte = 0;
	pObj->CacheFirstVisibleLine = 0;
}

/*********************************************************************
*
*   	_GetCursorLine
*
* Returns the line number of the cursor position.
*/
static int _GetCursorLine(MULTIEDIT_HANDLE hObj, const MULTIEDIT_OBJ *pObj, const char *pText, int CursorPosChar)
{
	const char *pCursor;
	const char *pEndLine;
	int NumChars, ByteOffsetNewCursor, LineNumber = 0;
	ByteOffsetNewCursor = GUI_UC__NumChars2NumBytes(pText, CursorPosChar);
	pCursor = pText + ByteOffsetNewCursor;
	if (pObj->CacheLinePosByte < ByteOffsetNewCursor)
	{
		/* If cache pos < new position we can use it as start position */
		pText += pObj->CacheLinePosByte;
		LineNumber += pObj->CacheLineNumber;
	}
	while (*pText && (pCursor > pText))
	{
		NumChars = _WrapGetNumCharsDisp(hObj, pObj, pText);
		pEndLine = pText + GUI_UC__NumChars2NumBytes(pText, NumChars);
		pText += _WrapGetNumBytesToNextLine(hObj, pObj, pText);
		if (pCursor <= pEndLine)
		{
			if ((pCursor == pEndLine) && (pEndLine == pText) && *pText)
			{
				LineNumber++;
			}
			break;
		}
		LineNumber++;
	}
	return LineNumber;
}

/*********************************************************************
*
*   	_GetCursorXY
*/
static void _GetCursorXY(MULTIEDIT_HANDLE hObj, /*const*/ MULTIEDIT_OBJ *pObj, int *px, int *py)
{
	if (pObj->InvalidFlags & INVALID_CURSORXY)
	{
		int CursorLine = 0, x = 0;
		GUI_SetFont(pObj->pFont);
		if (pObj->hText)
		{
			const char *pLine;
			const char *pCursor;
			pLine = (const char *) GUI_ALLOC_h2p(pObj->hText);
			pCursor = pLine + pObj->CursorPosByte;
			CursorLine = pObj->CursorLine;
			pLine = _GetpLine(hObj, pObj, CursorLine);
			while (pLine < pCursor)
			{
				x += _GetCharDistX(pObj, pLine);
				pLine += GUI_UC_GetCharSize(pLine);
			}
		}
		pObj->CursorPosX = x;
		pObj->CursorPosY = CursorLine * GUI_GetFontDistY();
		pObj->InvalidFlags &= ~INVALID_CURSORXY;
	}
	*px = pObj->CursorPosX;
	*py = pObj->CursorPosY;
}

/*********************************************************************
*
*   	_InvalidateCursorXY
*/
static void _InvalidateCursorXY(MULTIEDIT_OBJ *pObj)
{
	pObj->InvalidFlags |= INVALID_CURSORXY;
}

/*********************************************************************
*
*   	_SetScrollState
*/
static void _SetScrollState(WM_HWIN hObj)
{
	MULTIEDIT_OBJ* pObj = MULTIEDIT_H2P(hObj);
	WIDGET__SetScrollState(hObj, &pObj->ScrollStateV, &pObj->ScrollStateH);
}

/*********************************************************************
*
*   	_CalcScrollPos
*
* Purpose:
*   Find out if the current position of the cursor is still in the
*   visible area. If it is not, the scroll position is updated.
*   Needs to be called every time the cursor is move, wrap, font or
*   window size are changed.
*/
static void _CalcScrollPos(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ *pObj)
{
	int xCursor, yCursor;
	_GetCursorXY(hObj, pObj, &xCursor, &yCursor);
	yCursor /= GUI_GetYDistOfFont(pObj->pFont);
	WM_CheckScrollPos(&pObj->ScrollStateV, yCursor, 0, 0);  	 /* Vertical */
	WM_CheckScrollPos(&pObj->ScrollStateH, xCursor, 30, 30);	 /* Horizontal */
	_SetScrollState(hObj);

⌨️ 快捷键说明

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