📄 pureedit.c
字号:
/*
*******************************************************************************
* The real-time kernel "rtCell" *
* Copyright 2005 taowentao, allrights reserved. *
* File : PureEdit.c *
* By : taowentao 2006-09-02 2007-05-20 *
*******************************************************************************
*/
#if !defined(PUREEDIT_H)
#include "giCell\Wins\include\PureEdit.h"
#endif
#include <mem.h>
#include <string.h>
/*
*******************************************************************************
* *
*******************************************************************************
*/
static COLOR editColor = GD_WHITE;
static COLOR selectColor = GD_BLUE;
static COLOR textColor[2] = {GD_BLACK, GD_WHITE};
/*
*******************************************************************************
* *
*******************************************************************************
*/
static void GetTextOrgByCursor(PEDIT* pEdit)
{
int xSize, ySize;
POINT pt;
RECT r = pEdit->pView->viewRect;
xSize = TextWidth(pEdit->pText);
ySize = TextHeight(pEdit->pText);
GetOrgFromAlign(xSize, ySize, &r, pEdit->textAlign, &pt);
xSize = GetCharX(pt.x, pEdit->xCursor, pEdit->pText);
if (xSize < (r.left+1)) {
pt.x += (r.left - xSize + 2);
} else if (xSize > (r.right-1)) {
pt.x -= (xSize - r.right + 2);
}
pEdit->ptText = pt;
}
static void PEditPaint(VIEW *pView)
{
PEDIT* pEdit;
COLOR clr;
int xSize, ySize;
POINT pt;
RECT r = pView->viewRect;
pEdit = OBJ_FROM_VIEW(pView);
FillRect(&r, pEdit->editColor);
xSize = TextWidth(pEdit->pText);
ySize = TextHeight(pEdit->pText);
GetTextOrgByCursor(pEdit);
pt = pEdit->ptText;
if (pEdit->Status & CTRL_MOUSE_ENTER) clr = MOUSEENTERCOLOR;
else clr = pEdit->textColor[0];
DrawText(pt.x, pt.y, pEdit->pText, clr);
if (pEdit->Status & CTRL_FOCUSSED) {
int start, end;
if (pEdit->selStart != pEdit->selEnd) {
BYTE ch;
if (pEdit->selStart > pEdit->selEnd) {
start = pEdit->selEnd;
end = pEdit->selStart;
} else {
start = pEdit->selStart;
end = pEdit->selEnd;
}
r.left = GetCharX(pt.x, start, pEdit->pText);
r.right = GetCharX(pt.x, end, pEdit->pText);
r.top = pt.y;
r.bottom = r.top + ySize - 1;
FillRect(&r, pEdit->selectColor);
if (end < pEdit->textLength) {
ch = pEdit->pText[end];
pEdit->pText[end] = 0;
}
DrawText(r.left, r.top, pEdit->pText+start, pEdit->textColor[1]);
if (end < pEdit->textLength) {
pEdit->pText[end] = ch;
}
}
if (pEdit->Status & CTRL_PEDIT_CURSOR) {
xSize = GetCharX(pt.x, pEdit->xCursor, pEdit->pText);
clr = GD_BLACK;
if (pEdit->selStart != pEdit->selEnd) {
if ((pEdit->xCursor >= start) &&
(pEdit->xCursor <= end)) {
clr = GD_WHITE;
}
}
DrawVLine(xSize-1, pt.y, pt.y+ySize-1, clr);
DrawVLine(xSize, pt.y, pt.y+ySize-1, clr);
}
}
}
static void SetCursor(PEDIT *pEdit, int x)
{
int xSize, xCh, i, sLen;
POINT pt;
BYTE *s = pEdit->pText;
xSize = TextWidth(pEdit->pText);
GetTextOrgByCursor(pEdit);
pt = pEdit->ptText;
sLen = strlen(s);
if (x <= pt.x) {
pEdit->xCursor = 0;
} else if (x >= (pt.x+xSize)) {
pEdit->xCursor = sLen;
} else {
for (i = 0, xSize = pt.x; i < sLen; i++) {
xCh = CharWidth(*(s + i));
if (x < (xSize + (xCh >> 1))) break;
xSize += xCh;
}
pEdit->xCursor = i;
}
}
static CBOOL DelSelected(PEDIT *pEdit)
{
int nCopy, start, end;
if (pEdit->Status & CTRL_PEDIT_READOMLY)
return (false);
if (pEdit->selStart != pEdit->selEnd) {
const BYTE *s = pEdit->pText;
if (pEdit->selStart > pEdit->selEnd) {
start = pEdit->selEnd;
end = pEdit->selStart;
} else {
start = pEdit->selStart;
end = pEdit->selEnd;
}
pEdit->xCursor = start;
nCopy = pEdit->textLength-end;
memmove(s + start, s + end, nCopy);
pEdit->selStart = 0; pEdit->selEnd = 0;
return (true);
} else {
return (false);
}
}
static void PEditAddChar(PEDIT *pEdit, BYTE ch)
{
int sLen, nCopy;
BYTE *s;
if (pEdit->Status & CTRL_PEDIT_READOMLY)
return;
DelSelected(pEdit);
s = pEdit->pText;
sLen = strlen(s);
if (pEdit->Status & CTRL_PEDIT_INSERT) {
if (sLen < (pEdit->textLength - 1)) {
nCopy = pEdit->textLength - pEdit->xCursor - 1;
memmove(s + pEdit->xCursor + 1, s + pEdit->xCursor, nCopy);
*(s + pEdit->xCursor) = ch;
if (pEdit->xCursor < (pEdit->textLength - 1))
pEdit->xCursor++;
}
} else {
*(s + pEdit->xCursor) = ch;
if (pEdit->xCursor < (pEdit->textLength - 1))
pEdit->xCursor++;
}
}
static void PEditKeyDown(VMSG *pMsg)
{
PEDIT *pEdit;
BYTE *s;
int sLen, nCopy;
KEY_INF ki;
pEdit = OBJ_FROM_VIEW(pMsg->pView);
ki.raw = pMsg->vParam;
s = pEdit->pText;
sLen = strlen(s);
if (ki.inf.ctrl) {
if ((ki.inf.scan == SCANCODE_C) || (ki.inf.scan == SCANCODE_X)) {
if (pEdit->selStart != pEdit->selEnd) {
int start, end;
if (pEdit->selStart > pEdit->selEnd) {
start = pEdit->selEnd;
end = pEdit->selStart;
} else {
start = pEdit->selStart;
end = pEdit->selEnd;
}
AddToClipBoard(pEdit->pText+start, end-start);
if (ki.inf.scan == SCANCODE_X) DelSelected(pEdit);
}
return;
} else if (ki.inf.scan == SCANCODE_V) {
nCopy = GetClipBoardContentSize();
if (nCopy > 0) {
BYTE *scr = (BYTE *)GetClipBoardBuf();
for (; nCopy > 0; scr ++, nCopy --)
PEditAddChar(pEdit, (*scr));
}
return;
} else if (ki.inf.scan == SCANCODE_A) {
pEdit->selStart = 0;
pEdit->selEnd = sLen;
pEdit->xCursor = sLen;
return;
}
}
switch (ki.inf.key) {
case KEY_HOME:
pEdit->xCursor = 0;
pEdit->selStart = 0; pEdit->selEnd = 0;
break;
case KEY_END:
pEdit->xCursor = sLen;
pEdit->selStart = 0; pEdit->selEnd = 0;
break;
case KEY_RIGHT:
pEdit->selStart = 0; pEdit->selEnd = 0;
if (pEdit->xCursor < (pEdit->textLength - 1)) {
if (pEdit->xCursor < sLen)
pEdit->xCursor ++;
}
break;
case KEY_LEFT:
pEdit->selStart = 0; pEdit->selEnd = 0;
if (pEdit->xCursor > 0)
pEdit->xCursor--;
break;
case KEY_BACKSPACE:
if (DelSelected(pEdit) == false) {
if ((sLen > 0) && (pEdit->xCursor > 0)) {
nCopy = pEdit->textLength - pEdit->xCursor;
strncpy(s + pEdit->xCursor - 1, s + pEdit->xCursor, nCopy);
*(s + sLen - 1) = 0;
pEdit->xCursor--;
}
}
break;
case KEY_DELETE:
if (DelSelected(pEdit) == false) {
if ((sLen > 0) && (pEdit->xCursor < sLen)) {
if (sLen > 1) {
nCopy = pEdit->textLength - pEdit->xCursor - 1;
strncpy(s + pEdit->xCursor, s + pEdit->xCursor + 1, nCopy);
}
*(s + sLen - 1) = 0;
}
}
break;
case KEY_INSERT:
if (pEdit->Status & CTRL_PEDIT_INSERT)
pEdit->Status &= (~CTRL_PEDIT_INSERT);
else
pEdit->Status |= CTRL_PEDIT_INSERT;
break;
case KEY_ENTER:
case KEY_ESCAPE:
break;
default:
if ((ki.inf.key >= 0x20) && (ki.inf.key <= 0x7f)) {
PEditAddChar(pEdit, (BYTE)(ki.inf.key));
}
break;
}
}
static CBOOL _cdecl_ PEditViewProc(VMSG *pMsg)
{
PEDIT *pEdit = OBJ_FROM_VIEW(pMsg->pView);
KEY_INF ki;
MOUSE_INF mi;
RECT r;
POINT pt = pMsg->pt;
switch (pMsg->MsgID) {
case TIMERM_OUT:
pEdit->Timer ++;
if (pEdit->Timer >= CTRL_PEDIT_TIME) {
pEdit->Timer = 0;
if (pEdit->Status & CTRL_PEDIT_CURSOR)
pEdit->Status &= (~CTRL_PEDIT_CURSOR);
else
pEdit->Status |= CTRL_PEDIT_CURSOR;
GetTextOrgByCursor(pEdit);
r.left = GetCharX(pEdit->ptText.x, pEdit->xCursor, pEdit->pText)-1;
r.right = r.left+1; r.top = pEdit->ptText.y;
r.bottom = r.top+TextHeight(pEdit->pText)-1;
UpdateViewRect(pMsg->pView, &r);
}
return (true);
case KEYM_KEY_DOWN:
if (pEdit->Status & CTRL_FOCUSSED) {
PEditKeyDown(pMsg);
UpdateView(pMsg->pView);
if (pEdit->pKeyDown != NULL) {
ki.raw = pMsg->vParam;
(*(pEdit->pKeyDown))(ki);
}
}
return (true);
case MSM_LB_DOWN:
if ((pEdit->Status & CTRL_FOCUSSED)) {
pEdit->Status |= CTRL_MOUSE_ENTER;
r = pMsg->pView->viewRect;
if (IsInRect(pt.x, pt.y, &r) == false) return (true);
SetCursor(pEdit, pt.x);
pEdit->selStart = pEdit->xCursor;
pEdit->selEnd = pEdit->xCursor;
pEdit->ptCatch = pt;
pEdit->Status |= CTRL_MOUSE_CATCH;
pEdit->Status |= CTRL_CATCH_MOVE;
UpdateView(pMsg->pView);
}
return (true);
case MSM_LB_UP:
if ((pEdit->Status & CTRL_MOUSE_CATCH) == 0) return (true);
pEdit->Status &= ~(CTRL_MOUSE_CATCH);
UpdateView(pMsg->pView);
return (true);
case MSM_MS_MOVE:
mi.raw = pMsg->vParam;
if ((pEdit->Status & CTRL_MOUSE_CATCH) && (mi.inf.lbtn != 0)) {
if (pEdit->Status & CTRL_CATCH_MOVE) {
SetCursor(pEdit, pt.x);
pEdit->selEnd = pEdit->xCursor;
UpdateView(pMsg->pView);
}
}
return (true);
case MSM_MS_ENTER:
SetMouseCursor(TEXT);
pEdit->Status |= CTRL_MOUSE_ENTER;
UpdateView(pMsg->pView);
return (true);
default:
return (CtrlViewProc(pMsg, PEditPaint, &(pEdit->Status)));
}
}
PEDIT* CreatePureEdit(int left, int top, int width, int height, VIEW* pParent,
BYTE *pText, PKEYDOWN pKeyDown, CWORD Align, CWORD textLen)
{
PEDIT *pEdit;
VIEW *pView;
if (pParent == NULL)
return (NULL);
pView = CreateControl(left, top, width, height, pParent, 0,
PEditViewProc, sizeof(PEDIT)+textLen+1);
if (pView == NULL) return (NULL);
pEdit = OBJ_FROM_VIEW(pView);
pEdit->pView = pView;
pEdit->textColor[0] = textColor[0];
pEdit->textColor[1] = textColor[1];
pEdit->pKeyDown = pKeyDown;
pEdit->ptCatch.x = 0; pEdit->ptCatch.y = 0;
pEdit->editColor = editColor;
pEdit->selectColor = selectColor;
pEdit->Status = CTRL_PEDIT_INSERT;
pEdit->textAlign = Align;
pEdit->textLength = textLen;
pEdit->pText = ((BYTE *)(pEdit+1));
memcpy(pEdit->pText, pText, pEdit->textLength);
pEdit->pText[pEdit->textLength] = 0;
pEdit->selStart = 0; pEdit->selEnd = 0;
pEdit->Timer = 0;
pEdit->xCursor = 0;
ShowView(pEdit->pView);
return (pEdit);
}
const BYTE * GetPureEditText(PEDIT *pEdit)
{
if (pEdit != NULL)
return (pEdit->pText);
else
return (NULL);
}
void DeletePureEdit(PEDIT *pEdit)
{
if (pEdit == NULL) return;
DeleteView(pEdit->pView);
}
/*
*******************************************************************************
* *
*******************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -