📄 multiedit.c
字号:
x = 0;
}
}
if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
while (--WrapChars > 0) {
Char = GUI_UC_GetCharCode(pLine);
SizeX += _GetCharDistX(pObj, pLine);
if (!Char || (SizeX > x)) {
break;
}
pLine += GUI_UC_GetCharSize(pLine);
}
CursorPosChar = GUI_UC__NumBytes2NumChars(pText, pLine - pText);
} else {
CursorPosChar = GUI_UC__NumBytes2NumChars(pText, pLine - pText) + GUI__GetCursorPosChar(pLine, x, WrapChars);
}
}
_SetCursorPos(hObj, pObj, CursorPosChar);
}
/*********************************************************************
*
* _MoveCursorUp
*/
static void _MoveCursorUp(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
int xPos, yPos;
_GetCursorXY(hObj, pObj, &xPos, &yPos);
yPos -= GUI_GetYDistOfFont(pObj->pFont);
_SetCursorXY(hObj, pObj, xPos, yPos);
}
/*********************************************************************
*
* _MoveCursorDown
*/
static void _MoveCursorDown(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
int xPos, yPos;
_GetCursorXY(hObj, pObj, &xPos, &yPos);
yPos += GUI_GetYDistOfFont(pObj->pFont);
_SetCursorXY(hObj, pObj, xPos, yPos);
}
/*********************************************************************
*
* _MoveCursor2NextLine
*/
static void _MoveCursor2NextLine(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
int xPos, yPos;
_GetCursorXY(hObj, pObj, &xPos, &yPos);
yPos += GUI_GetYDistOfFont(pObj->pFont);
_SetCursorXY(hObj, pObj, 0, yPos);
}
/*********************************************************************
*
* _MoveCursor2LineEnd
*/
static void _MoveCursor2LineEnd(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
int xPos, yPos;
_GetCursorXY(hObj, pObj, &xPos, &yPos);
_SetCursorXY(hObj, pObj, 0x7FFF, yPos);
}
/*********************************************************************
*
* _MoveCursor2LinePos1
*/
static void _MoveCursor2LinePos1(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
int xPos, yPos;
_GetCursorXY(hObj, pObj, &xPos, &yPos);
_SetCursorXY(hObj, pObj, 0, yPos);
}
/*********************************************************************
*
* _IsOverwriteAtThisChar
*/
static int _IsOverwriteAtThisChar(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj) {
int r = 0;
if (pObj->hText && !(pObj->Flags & MULTIEDIT_CF_INSERT)) {
const char *pText;
int CurPos, Line1, Line2;
U16 Char;
pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
Line1 = pObj->CursorLine;
CurPos = _CalcNextValidCursorPos(hObj, pObj, pObj->CursorPosChar + 1, 0, 0);
Line2 = _GetCursorLine(hObj, pObj, pText, CurPos);
pText += pObj->CursorPosByte;
Char = GUI_UC_GetCharCode(pText);
if (Char) {
if ((Line1 == Line2) || (pObj->Flags & MULTIEDIT_SF_PASSWORD)) {
r = 1;
} else {
if (Char != '\n') {
if ((Char != ' ') || (pObj->WrapMode == GUI_WRAPMODE_CHAR)) {
r = 1;
}
}
}
}
}
return r;
}
/*********************************************************************
*
* _GetCursorSizeX
*
* Returns the width of the cursor to be draw according to the
* insert mode flag and the cursor position.
*/
static int _GetCursorSizeX(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ* pObj, int * pIsRTL) {
if (_IsOverwriteAtThisChar(hObj, pObj)) {
#if (GUI_SUPPORT_ARABIC)
if (pObj->Flags & MULTIEDIT_SF_PASSWORD) {
const char *pText;
pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
pText += pObj->CursorPosByte;
return _GetCharDistX(pObj, pText);
} else {
const char * pText;
U16 Prev = 0, Char, Next = 0, Glyph;
pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
if (pObj->CursorPosChar) {
int NumChars = pObj->CursorPosChar;
while (--NumChars) {
pText += GUI_UC_GetCharSize(pText);
}
Prev = GUI_UC__GetCharCodeInc(&pText);
Char = GUI_UC__GetCharCodeInc(&pText);
} else {
pText += pObj->CursorPosByte;
Char = GUI_UC__GetCharCodeInc(&pText);
}
if (pObj->CursorPosChar < (pObj->NumChars - 1)) {
Next = GUI_UC_GetCharCode(pText);
}
Glyph = GUI__GetPresentationForm(Char, Next, Prev, 0);
if (Char != 0x20) {
*pIsRTL = GUI__IsArabicCharacter(Char) ? 1 : 0;
} else {
*pIsRTL = GUI__IsArabicCharacter(Prev) ? 1 : 0;
}
return GUI_GetCharDistX(Glyph);
}
#else
const char *pText;
*pIsRTL = 0;
pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
pText += pObj->CursorPosByte;
return _GetCharDistX(pObj, pText);
#endif
} else {
#if (GUI_SUPPORT_ARABIC)
const char * pText;
U16 Prev = 0, Char;
pText = (const char *)GUI_ALLOC_h2p(pObj->hText);
if (pObj->CursorPosChar) {
int NumChars = pObj->CursorPosChar;
while (--NumChars) {
pText += GUI_UC_GetCharSize(pText);
}
Prev = GUI_UC__GetCharCodeInc(&pText);
Char = GUI_UC_GetCharCode(pText);
} else {
pText += pObj->CursorPosByte;
Char = GUI_UC_GetCharCode(pText);
}
if (Char != 0x20) {
*pIsRTL = GUI__IsArabicCharacter(Char) ? 1 : 0;
} else {
*pIsRTL = GUI__IsArabicCharacter(Prev) ? 1 : 0;
}
#endif
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, IsRTL = 0;
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;
}
}
if (pObj->Align == GUI_TA_RIGHT) {
r.x0 += ScrollPosX;
r.x1 += ScrollPosX;
}
/* 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)) {
int CursorSize;
_GetCursorXY(hObj, pObj, &x, &y);
CursorSize = _GetCursorSizeX(hObj, pObj, &IsRTL);
if (IsRTL) {
r.x0 = x + xOff - CursorSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -