📄 textbox.c
字号:
/* ------------- textbox.c ------------ */
#include "dflat.h"
static void ComputeWindowTop(WINDOW);
static void ComputeWindowLeft(WINDOW);
static int ComputeVScrollBox(WINDOW);
static int ComputeHScrollBox(WINDOW);
static void MoveScrollBox(WINDOW, int);
static char *GetTextLine(WINDOW, int);
BOOL VSliding;
BOOL HSliding;
/* ------------ ADDTEXT Message -------------- */
static BOOL AddTextMsg(WINDOW wnd, char *txt)
{
/* --- append text to the textbox's buffer --- */
unsigned adln = strlen(txt);
if (adln > (unsigned)0xfff0)
return FALSE;
if (wnd->text != NULL) {
/* ---- appending to existing text ---- */
unsigned txln = strlen(wnd->text);
if ((long)txln+adln > (unsigned) 0xfff0)
return FALSE;
if (txln+adln > wnd->textlen) {
wnd->text = DFrealloc(wnd->text, txln+adln+3);
wnd->textlen = txln+adln+1;
}
}
else {
/* ------ 1st text appended ------ */
wnd->text = DFcalloc(1, adln+3);
wnd->textlen = adln+1;
}
wnd->TextChanged = TRUE;
if (wnd->text != NULL) {
/* ---- append the text ---- */
strcat(wnd->text, txt);
strcat(wnd->text, "\n");
BuildTextPointers(wnd);
return TRUE;
}
return FALSE;
}
/* ------------ DELETETEXT Message -------------- */
static void DeleteTextMsg(WINDOW wnd, int lno)
{
char *cp1 = TextLine(wnd, lno);
--wnd->wlines;
if (lno == wnd->wlines)
*cp1 = '\0';
else {
char *cp2 = TextLine(wnd, lno+1);
memmove(cp1, cp2, strlen(cp2)+1);
}
BuildTextPointers(wnd);
}
/* ------------ INSERTTEXT Message -------------- */
static void InsertTextMsg(WINDOW wnd, char *txt, int lno)
{
if (AddTextMsg(wnd, txt)) {
int len = strlen(txt)+1;
char *cp2 = TextLine(wnd, lno);
char *cp1 = cp2+len;
memmove(cp1, cp2, strlen(cp2)-len);
strcpy(cp2, txt);
*(cp2+len-1) = '\n';
BuildTextPointers(wnd);
wnd->TextChanged = TRUE;
}
}
/* ------------ SETTEXT Message -------------- */
static void SetTextMsg(WINDOW wnd, char *txt)
{
unsigned char *tp, *ep, *ttp;
unsigned int len = 0;
int x = 0, n, rtn;
tp = txt;
while (*tp) {
if (*tp == '\t')
{
/* --- tab, adjust the buffer length --- */
int sps = cfg.Tabs - (x % cfg.Tabs);
len += sps;
x += sps;
}
else
{
/* --- not a tab, count the character --- */
len++;
x++;
}
if (*tp == '\n')
x = 0; /* newline, reset x --- */
tp++;
}
/* -- assign new text value to textbox buffer -- */
SendMessage(wnd, CLEARTEXT, 0, 0);
wnd->textlen = len;
wnd->text=DFrealloc(wnd->text, len + 1);
wnd->text[len] = '\0';
ep = DFcalloc(1, len + 1); /* allocate a buffer */
/* --- detab the input file --- */
tp = txt;
ttp = ep;
x = 0;
while (*tp)
{
if (*tp == '\t')
{
if((x % cfg.Tabs) == 0)
n = cfg.Tabs;
else
n = cfg.Tabs - (x % cfg.Tabs);
for( ; n; n--, ttp++, x++)
*ttp = ' ';
}
else
{
*ttp++ = *tp;
x++;
if (*tp == '\n')
x = 0;
}
tp++;
}
*ttp = '\0';
strcpy(wnd->text, ep);
free(ep);
BuildTextPointers(wnd);
}
/* ------------ CLEARTEXT Message -------------- */
static void ClearTextMsg(WINDOW wnd)
{
/* ----- clear text from textbox ----- */
if (wnd->text != NULL)
free(wnd->text);
wnd->text = NULL;
wnd->textlen = 0;
wnd->wlines = 0;
wnd->textwidth = 0;
wnd->wtop = wnd->wleft = 0;
ClearTextBlock(wnd);
ClearTextPointers(wnd);
}
/* ------------ KEYBOARD Message -------------- */
static int KeyboardMsg(WINDOW wnd, PARAM p1)
{
switch ((int) p1) {
case UP:
return SendMessage(wnd,SCROLL,FALSE,0);
case DN:
return SendMessage(wnd,SCROLL,TRUE,0);
case FWD:
return SendMessage(wnd,HORIZSCROLL,TRUE,0);
case LARROW:
return SendMessage(wnd,HORIZSCROLL,FALSE,0);
case PGUP:
return SendMessage(wnd,SCROLLPAGE,FALSE,0);
case PGDN:
return SendMessage(wnd,SCROLLPAGE,TRUE,0);
case CTRL_PGUP:
return SendMessage(wnd,HORIZPAGE,FALSE,0);
case CTRL_PGDN:
return SendMessage(wnd,HORIZPAGE,TRUE,0);
case HOME:
return SendMessage(wnd,SCROLLDOC,TRUE,0);
case END:
return SendMessage(wnd,SCROLLDOC,FALSE,0);
default:
break;
}
return FALSE;
}
/* ------------ LEFT_BUTTON Message -------------- */
static int LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
int mx = (int) p1 - GetLeft(wnd);
int my = (int) p2 - GetTop(wnd);
if (TestAttribute(wnd, VSCROLLBAR) &&
mx == WindowWidth(wnd)-1) {
/* -------- in the right border ------- */
if (my == 0 || my == ClientHeight(wnd)+1)
/* --- above or below the scroll bar --- */
return FALSE;
if (my == 1)
/* -------- top scroll button --------- */
return SendMessage(wnd, SCROLL, FALSE, 0);
if (my == ClientHeight(wnd))
/* -------- bottom scroll button --------- */
return SendMessage(wnd, SCROLL, TRUE, 0);
/* ---------- in the scroll bar ----------- */
if (!VSliding && my-1 == wnd->VScrollBox) {
RECT rc;
VSliding = TRUE;
rc.lf = rc.rt = GetRight(wnd);
rc.tp = GetTop(wnd)+2;
rc.bt = GetBottom(wnd)-2;
return SendMessage(NULL, MOUSE_TRAVEL,
(PARAM) &rc, 0);
}
if (my-1 < wnd->VScrollBox)
return SendMessage(wnd,SCROLLPAGE,FALSE,0);
if (my-1 > wnd->VScrollBox)
return SendMessage(wnd,SCROLLPAGE,TRUE,0);
}
if (TestAttribute(wnd, HSCROLLBAR) &&
my == WindowHeight(wnd)-1) {
/* -------- in the bottom border ------- */
if (mx == 0 || my == ClientWidth(wnd)+1)
/* ------ outside the scroll bar ---- */
return FALSE;
if (mx == 1)
return SendMessage(wnd, HORIZSCROLL,FALSE,0);
if (mx == WindowWidth(wnd)-2)
return SendMessage(wnd, HORIZSCROLL,TRUE,0);
if (!HSliding && mx-1 == wnd->HScrollBox) {
/* --- hit the scroll box --- */
RECT rc;
rc.lf = GetLeft(wnd)+2;
rc.rt = GetRight(wnd)-2;
rc.tp = rc.bt = GetBottom(wnd);
/* - keep the mouse in the scroll bar - */
SendMessage(NULL,MOUSE_TRAVEL,(PARAM)&rc,0);
HSliding = TRUE;
return TRUE;
}
if (mx-1 < wnd->HScrollBox)
return SendMessage(wnd,HORIZPAGE,FALSE,0);
if (mx-1 > wnd->HScrollBox)
return SendMessage(wnd,HORIZPAGE,TRUE,0);
}
return FALSE;
}
/* ------------ MOUSE_MOVED Message -------------- */
static BOOL MouseMovedMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
int mx = (int) p1 - GetLeft(wnd);
int my = (int) p2 - GetTop(wnd);
if (VSliding) {
/* ---- dragging the vertical scroll box --- */
if (my-1 != wnd->VScrollBox) {
foreground = FrameForeground(wnd);
background = FrameBackground(wnd);
wputch(wnd, SCROLLBARCHAR, WindowWidth(wnd)-1,
wnd->VScrollBox+1);
wnd->VScrollBox = my-1;
wputch(wnd, SCROLLBOXCHAR, WindowWidth(wnd)-1,
my);
}
return TRUE;
}
if (HSliding) {
/* --- dragging the horizontal scroll box --- */
if (mx-1 != wnd->HScrollBox) {
foreground = FrameForeground(wnd);
background = FrameBackground(wnd);
wputch(wnd, SCROLLBARCHAR, wnd->HScrollBox+1,
WindowHeight(wnd)-1);
wnd->HScrollBox = mx-1;
wputch(wnd, SCROLLBOXCHAR, mx, WindowHeight(wnd)-1);
}
return TRUE;
}
return FALSE;
}
/* ------------ BUTTON_RELEASED Message -------------- */
static void ButtonReleasedMsg(WINDOW wnd)
{
if (HSliding || VSliding) {
/* release the mouse ouside the scroll bar */
SendMessage(NULL, MOUSE_TRAVEL, 0, 0);
VSliding ? ComputeWindowTop(wnd):ComputeWindowLeft(wnd);
SendMessage(wnd, PAINT, 0, 0);
SendMessage(wnd, KEYBOARD_CURSOR, 0, 0);
VSliding = HSliding = FALSE;
}
}
/* ------------ SCROLL Message -------------- */
static BOOL ScrollMsg(WINDOW wnd, PARAM p1)
{
/* ---- vertical scroll one line ---- */
if (p1) {
/* ----- scroll one line up ----- */
if (wnd->wtop+ClientHeight(wnd) >= wnd->wlines)
return FALSE;
wnd->wtop++;
}
else {
/* ----- scroll one line down ----- */
if (wnd->wtop == 0)
return FALSE;
--wnd->wtop;
}
if (isVisible(wnd)) {
RECT rc;
rc = ClipRectangle(wnd, ClientRect(wnd));
if (ValidRect(rc)) {
/* ---- scroll the window ----- */
if (wnd != inFocus)
SendMessage(wnd, PAINT, 0, 0);
else {
scroll_window(wnd, rc, (int)p1);
if (!(int)p1)
/* -- write top line (down) -- */
WriteTextLine(wnd,NULL,wnd->wtop,FALSE);
else {
/* -- write bottom line (up) -- */
int y=RectBottom(rc)-GetClientTop(wnd);
WriteTextLine(wnd, NULL,
wnd->wtop+y, FALSE);
}
}
}
/* ---- reset the scroll box ---- */
if (TestAttribute(wnd, VSCROLLBAR)) {
int vscrollbox = ComputeVScrollBox(wnd);
if (vscrollbox != wnd->VScrollBox)
MoveScrollBox(wnd, vscrollbox);
}
}
return TRUE;
}
/* ------------ HORIZSCROLL Message -------------- */
static BOOL HorizScrollMsg(WINDOW wnd, PARAM p1)
{
/* --- horizontal scroll one column --- */
if (p1) {
/* --- scroll left --- */
if (wnd->wleft + ClientWidth(wnd)-1 >= wnd->textwidth)
return FALSE;
wnd->wleft++;
}
else {
/* --- scroll right --- */
if (wnd->wleft == 0)
return FALSE;
--wnd->wleft;
}
SendMessage(wnd, PAINT, 0, 0);
return TRUE;
}
/* ------------ SCROLLPAGE Message -------------- */
static void ScrollPageMsg(WINDOW wnd, PARAM p1)
{
/* --- vertical scroll one page --- */
if ((int) p1 == FALSE) {
/* ---- page up ---- */
if (wnd->wtop)
wnd->wtop -= ClientHeight(wnd);
}
else {
/* ---- page down ---- */
if (wnd->wtop+ClientHeight(wnd) < wnd->wlines) {
wnd->wtop += ClientHeight(wnd);
if (wnd->wtop>wnd->wlines-ClientHeight(wnd))
wnd->wtop=wnd->wlines-ClientHeight(wnd);
}
}
if (wnd->wtop < 0)
wnd->wtop = 0;
SendMessage(wnd, PAINT, 0, 0);
}
/* ------------ HORIZSCROLLPAGE Message -------------- */
static void HorizScrollPageMsg(WINDOW wnd, PARAM p1)
{
/* --- horizontal scroll one page --- */
if ((int) p1 == FALSE)
/* ---- page left ----- */
wnd->wleft -= ClientWidth(wnd);
else {
/* ---- page right ----- */
wnd->wleft += ClientWidth(wnd);
if (wnd->wleft > wnd->textwidth-ClientWidth(wnd))
wnd->wleft = wnd->textwidth-ClientWidth(wnd);
}
if (wnd->wleft < 0)
wnd->wleft = 0;
SendMessage(wnd, PAINT, 0, 0);
}
/* ------------ SCROLLDOC Message -------------- */
static void ScrollDocMsg(WINDOW wnd, PARAM p1)
{
/* --- scroll to beginning or end of document --- */
if ((int) p1)
wnd->wtop = wnd->wleft = 0;
else if (wnd->wtop+ClientHeight(wnd) < wnd->wlines){
wnd->wtop = wnd->wlines-ClientHeight(wnd);
wnd->wleft = 0;
}
SendMessage(wnd, PAINT, 0, 0);
}
/* ------------ PAINT Message -------------- */
static void PaintMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
/* ------ paint the client area ----- */
RECT rc, rcc;
int y;
char blankline[201];
/* ----- build the rectangle to paint ----- */
if ((RECT *)p1 == NULL)
rc=RelativeWindowRect(wnd, WindowRect(wnd));
else
rc= *(RECT *)p1;
if (TestAttribute(wnd, HASBORDER) &&
RectRight(rc) >= WindowWidth(wnd)-1) {
if (RectLeft(rc) >= WindowWidth(wnd)-1)
return;
RectRight(rc) = WindowWidth(wnd)-2;
}
rcc = AdjustRectangle(wnd, rc);
if (!p2 && wnd != inFocus)
ClipString++;
/* ----- blank line for padding ----- */
memset(blankline, ' ', SCREENWIDTH);
blankline[RectRight(rcc)+1] = '\0';
/* ------- each line within rectangle ------ */
for (y = RectTop(rc); y <= RectBottom(rc); y++){
int yy;
/* ---- test outside of Client area ---- */
if (TestAttribute(wnd,
HASBORDER | HASTITLEBAR)) {
if (y < TopBorderAdj(wnd))
continue;
if (y > WindowHeight(wnd)-2)
continue;
}
yy = y-TopBorderAdj(wnd);
if (yy < wnd->wlines-wnd->wtop)
/* ---- paint a text line ---- */
WriteTextLine(wnd, &rc,
yy+wnd->wtop, FALSE);
else {
/* ---- paint a blank line ---- */
SetStandardColor(wnd);
writeline(wnd, blankline+RectLeft(rcc),
RectLeft(rcc)+BorderAdj(wnd), y, FALSE);
}
}
/* ------- position the scroll box ------- */
if (TestAttribute(wnd, VSCROLLBAR|HSCROLLBAR)) {
int hscrollbox = ComputeHScrollBox(wnd);
int vscrollbox = ComputeVScrollBox(wnd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -