📄 multiedit.c
字号:
r.x1 = r.x0 + CursorSize - 1;
} else {
r.x0 = x + xOff;
r.x1 = r.x0 + CursorSize - 1;
}
r.y0 = y + yOff;
r.y1 = r.y0 + FontSizeY - 1;
if (pObj->Align == GUI_TA_RIGHT) {
r.x0 += ScrollPosX << 1;
r.x1 += ScrollPosX << 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;
}
/*********************************************************************
*
* _SetText
*/
static void _SetText(MULTIEDIT_HANDLE hObj, MULTIEDIT_OBJ * pObj, const char * pNew) {
int NumCharsNew, NumCharsOld, NumBytesNew, NumBytesOld;
char * pText;
NumCharsNew = NumCharsOld = NumBytesNew = NumBytesOld = 0;
if (pObj->hText) {
pText = (char*) GUI_ALLOC_h2p(pObj->hText);
pText += GUI_UC__NumChars2NumBytes(pText, pObj->NumCharsPrompt);
NumCharsOld = GUI__GetNumChars(pText);
NumBytesOld = GUI_UC__NumChars2NumBytes(pText, NumCharsOld);
}
if (pNew) {
NumCharsNew = GUI__GetNumChars(pNew);
NumBytesNew = GUI_UC__NumChars2NumBytes(pNew, NumCharsNew);
}
if (_IsCharsAvailable(pObj, NumCharsNew - NumCharsOld)) {
if (_IsSpaceInBuffer(pObj, NumBytesNew - NumBytesOld)) {
pText = (char*) GUI_ALLOC_h2p(pObj->hText);
pText += GUI_UC__NumChars2NumBytes(pText, pObj->NumCharsPrompt);
if (pNew) {
strcpy(pText, pNew);
} else {
*pText = 0;
}
_SetCursorPos(hObj, pObj, pObj->NumCharsPrompt);
_InvalidateNumChars(pObj);
_InvalidateNumLines(pObj);
_InvalidateTextSizeX(pObj);
_InvalidateTextArea(hObj);
_InvalidateCursorXY(pObj); /* Invalidate X/Y position */
}
}
}
/*********************************************************************
*
* Private routines
*
**********************************************************************
*/
/*********************************************************************
*
* MULTIEDIT_h2p
*/
#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL
MULTIEDIT_OBJ* MULTIEDIT_h2p(MULTIEDIT_HANDLE h) {
MULTIEDIT_OBJ* p = (MULTIEDIT_OBJ*)GUI_ALLOC_h2p(h);
if (p) {
if (p->DebugId != MULTIEDIT_ID) {
GUI_DEBUG_ERROROUT("MULTIEDIT.c: Wrong handle type or Object not init'ed");
return 0;
}
}
return p;
}
#endif
/*********************************************************************
*
* Exported routines: Callback
*
**********************************************************************
*/
/*********************************************************************
*
* MULTIEDIT_Callback
*/
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_OBJ *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
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:
#if WIDGET_USE_PARENT_EFFECT
WIDGET_SetEffect(pMsg->hWinSrc, pObj->Widget.pEffect);
#endif
_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 */
/*********************************************************************
*
* MULTIEDIT_CreateEx
*/
MULTIEDIT_HANDLE MULTIEDIT_CreateEx(int x0, int y0, int xsize, int ysize, WM_HWIN hParent, int WinFlags, int ExFlags,
int Id, int BufferSize, const char* pText)
{
MULTIEDIT_HANDLE hObj;
/* Create the window */
WM_LOCK();
if ((xsize == 0) && (ysize == 0) && (x0 == 0) && (y0 == 0)) {
GUI_RECT Rect;
WM_GetClientRectEx(hParent, &Rect);
xsize = Rect.x1 - Rect.x0 + 1;
ysize = Rect.y1 - Rect.y0 + 1;
}
hObj = WM_CreateWindowAsChild(x0, y0, xsize, ysize, hParent, WinFlags, &MULTIEDIT_Callback,
sizeof(MULTIEDIT_OBJ) - sizeof(WM_Obj));
if (hObj) {
int i;
MULTIEDIT_OBJ * pObj;
pObj = (MULTIEDIT_OBJ *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
/* init widget specific variables */
WIDGET__Init(&pObj->Widget, Id, WIDGET_STATE_FOCUSSABLE);
/* init member variables */
MULTIEDIT_INIT_ID(pObj);
for (i = 0; i < NUM_DISP_MODES; i++) {
pObj->aBkColor[i] = _aDefaultBkColor[i];
pObj->aColor[i] = _aDefaultColor[i];
}
pObj->pFont = _pDefaultFont;
pObj->Flags = ExFlags;
pObj->CursorPosChar = 0;
pObj->CursorPosByte = 0;
pObj->HBorder = 1;
pObj->MaxNumChars = 0;
pObj->NumCharsPrompt = 0;
pObj->BufferSize = 0;
pObj->hText = 0;
if (BufferSize > 0) {
WM_HWIN hText;
if ((hText = GUI_ALLOC_AllocZero(BufferSize)) != 0) {
pObj->BufferSize = BufferSize;
pObj->hText = hText;
} else {
GUI_DEBUG_ERROROUT("MULTIEDIT_CreateEx failed to alloc buffer");
WM_DeleteWindow(hObj);
hObj = 0;
}
}
MULTIEDIT_SetText(hObj, pText);
_ManageScrollers(hObj);
} else {
GUI_DEBUG_ERROROUT_IF(hObj==0, "MULTIEDIT_CreateEx failed")
}
WM_UNLOCK();
return hObj;
}
/*********************************************************************
*
* Exported routines: Various methods
*
**********************************************************************
*/
/*********************************************************************
*
* MULTIEDIT_AddKey
*/
int MULTIEDIT_AddKey(MULTIEDIT_HANDLE hObj, U16 Key) {
int r = 0;
if (hObj) {
WM_LOCK();
r = _AddKey(hObj, Key);
WM_UNLOCK();
}
return r;
}
/*********************************************************************
*
* MULTIEDIT_AddText
*/
int MULTIEDIT_AddText(MULTIEDIT_HANDLE hObj, const char * s) {
int Result;
Result = 1;
if (hObj && s) {
MULTIEDIT_OBJ * pObj;
WM_LOCK();
pObj = MULTIEDIT_H2P(hObj);
if (!pObj->hText) {
_SetText(hObj, pObj, s);
} else {
char * pText;
int NumCharsNew, NumCharsOld, NumBytesNew, NumBytesOld;
pText = (char *)GUI_ALLOC_h2p(pObj->hText);
NumCharsOld = GUI__GetNumChars(pText);
NumBytesOld = GUI_UC__NumChars2NumBytes(pText, NumCharsOld);
NumCharsNew = GUI__GetNumChars(s);
if (pObj->MaxNumChars > 0) {
if ((NumCharsOld + NumCharsNew) > pObj->MaxNumChars) {
NumCharsNew = pObj->MaxNumChars - NumCharsOld;
}
}
if (NumCharsNew > 0) {
NumBytesNew = GUI_UC__NumChars2NumBytes(s, NumCharsNew);
if (_IsSpaceInBuffer(pObj, NumBytesNew)) {
pText = (char *)GUI_ALLOC_h2p(pObj->hText);
memmove(pText + pObj->CursorPosByte + NumBytesNew,
pText + pObj->CursorPosByte,
NumBytesOld - pObj->CursorPosByte);
memcpy(pText + pObj->CursorPosByte, s, NumBytesNew);
*(pText + NumBytesOld + NumBytesNew) = 0;
pObj->NumChars += NumCharsNew;
_SetCursorPos(hObj, pObj, pObj->CursorPosChar + NumCharsNew);
_InvalidateNumLines(pObj);
_InvalidateTextSizeX(pObj);
_InvalidateTextArea(hObj);
_InvalidateCursorXY(pObj);
_ClearCache(pObj);
WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
Result = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -