Category : Files from Magazines
Archive   : D-FLAT.ZIP
Filename : TEXTBOX.C

 
Output of file : TEXTBOX.C contained in archive : D-FLAT.ZIP
/* ------------- textbox.c ------------ */

#include
#include
#include
#include
#include "dflat.h"

static char *GetTextLine(WINDOW wnd, int selection);

static int HScrolling = FALSE;
static int VScrolling = FALSE;

int TextBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
{
int mx = (int) p1 - GetLeft(wnd);
int my = (int) p2 - GetTop(wnd);
switch (msg) {
case CREATE_WINDOW:
wnd->wlines = wnd->wtop = wnd->wleft =
wnd->textlen = wnd->textwidth = 0;
wnd->text = NULL;
wnd->HScrollBox = wnd->VScrollBox = 1;
ClearBlock(wnd);
break;
case ADDTEXT: {
/* ======== need to assure that length !> 64K ======= */
int adln = strlen((char *)p1)+2;
if (wnd->text != NULL) {
int txln = strlen(wnd->text);
if (txln+adln > wnd->textlen) {
wnd->text = realloc(wnd->text, txln+adln);
wnd->textlen = txln+adln-1;
}
}
else {
wnd->text = malloc(adln);
*wnd->text = '\0';
wnd->textlen = adln-1;
}
strcat(wnd->text, (char*) p1);
strcat(wnd->text, "\n");
wnd->wlines++;
wnd->textwidth = max(adln, wnd->textwidth);
break;
}
case SETTEXT: {
char *cp, *cp1;
SendMessage(wnd, CLEARTEXT, 0, 0);
wnd->text = cp = cp1 = (void *) p1;
wnd->textlen = max(strlen(cp)+1, (int) p2);
while ((cp = strchr(cp, '\n')) != NULL) {
wnd->wlines++;
cp++;
wnd->textwidth = max(wnd->textwidth, (int)(cp-cp1));
cp1 = cp;
}
break;
}
case CLEARTEXT:
if (wnd->text != NULL)
free(wnd->text);
wnd->text = NULL;
wnd->textlen = 0;
wnd->wlines = 0;
wnd->textwidth = 0;
wnd->wtop = wnd->wleft = 0;
ClearBlock(wnd);
break;
case SETFOCUS:
if (!p1 && isMultiLine(wnd))
ClearBlock(wnd);
break;
case KEYBOARD:
if (WindowMoving || WindowSizing)
break;
switch ((int) p1) {
case UP:
if (wnd->wtop)
SendMessage(wnd, SCROLL, FALSE, 0);
return TRUE;
case DN:
if (wnd->wtop+ClientHeight(wnd) < wnd->wlines)
SendMessage(wnd, SCROLL, TRUE, 0);
return TRUE;
case FWD:
SendMessage(wnd, HORIZSCROLL, TRUE, 0);
return TRUE;
case BS:
SendMessage(wnd, HORIZSCROLL, FALSE, 0);
return TRUE;
case PGUP:
if (wnd->wtop) {
wnd->wtop -= ClientHeight(wnd);
if (wnd->wtop < 0)
wnd->wtop = 0;
SendMessage(wnd, PAINT, 0, 0);
return TRUE;
}
return TRUE;
case PGDN:
if (wnd->wtop+ClientHeight(wnd) < wnd->wlines) {
wnd->wtop += ClientHeight(wnd);
if (wnd->wtop > wnd->wlines-ClientHeight(wnd))
wnd->wtop = wnd->wlines-ClientHeight(wnd);
SendMessage(wnd, PAINT, 0, 0);
return TRUE;
}
return TRUE;
case HOME:
if (wnd->wtop || wnd->wleft) {
wnd->wtop = wnd->wleft = 0;
SendMessage(wnd, PAINT, 0, 0);
}
return TRUE;
case END:
if (wnd->wtop+ClientHeight(wnd) < wnd->wlines) {
wnd->wtop = wnd->wlines-ClientHeight(wnd);
wnd->wleft = 0;
SendMessage(wnd, PAINT, 0, 0);
}
return TRUE;
default:
break;
}
break;
case LEFT_BUTTON:
if (WindowSizing || WindowMoving)
return FALSE;
if (TestAttribute(wnd, VSCROLLBAR) && (VScrolling ||
mx == WindowWidth(wnd)-1)) {

/* -------- in the right border ------- */
if (my == 0 || my == ClientHeight(wnd)+1)
/* ------ above or below the scroll bar ---- */
break;

/* ---------- in the scroll bar ----------- */

VScrolling = TRUE;

if (my == 1) {
/* -------- top scroll button --------- */
SendMessage(wnd, SCROLL, FALSE, 0);
return TRUE;
}
if (my == ClientHeight(wnd)) {
/* -------- bottom scroll button --------- */
SendMessage(wnd, SCROLL, TRUE, 0);
return TRUE;
}
if (my-1 != wnd->VScrollBox) {
int dir = my-1 > wnd->VScrollBox;

while (dir ? (my-1 > wnd->VScrollBox) :
(my-1 < wnd->VScrollBox)) {
if (!SendMessage(NULLWND, TESTMOUSE, 0, 0))
break;
SendMessage(wnd, SCROLL, dir, 0);
}
return TRUE;
}
}
if (TestAttribute(wnd, HSCROLLBAR) &&
(HScrolling || my == WindowHeight(wnd)-1)) {
/* -------- in the bottom border ------- */
if (mx == 0 || my == ClientWidth(wnd)+1)
/* ------ outside the scroll bar ---- */
break;

HScrolling = TRUE;

if (mx == 1) {
SendMessage(wnd, HORIZSCROLL, FALSE, 0);
return TRUE;
}
if (mx == WindowWidth(wnd)-2) {
SendMessage(wnd, HORIZSCROLL, TRUE, 0);
return TRUE;
}
if (mx-1 != wnd->HScrollBox) {
int dir = mx-1 > wnd->HScrollBox;
while (dir ? (mx-1 > wnd->HScrollBox) :
(mx-1 < wnd->HScrollBox)) {
if (!SendMessage(NULLWND, TESTMOUSE, 0, 0))
break;
SendMessage(wnd, HORIZSCROLL, dir, 0);
}
return TRUE;
}
}
break;
case BUTTON_RELEASED:
HScrolling = VScrolling = FALSE;
break;
case SCROLL:
if (isVisible(wnd)) {
if (p1 == 0) {
if (wnd->wtop == 0)
return FALSE;
}
else if (wnd->wtop+ClientHeight(wnd) >= wnd->wlines)
return FALSE;
if (p1)
wnd->wtop++;
else
--wnd->wtop;
SendMessage(wnd, PAINT, 0, 0);
return TRUE;
}
break;
case HORIZSCROLL:
if (p1 == 0 && wnd->wleft == 0)
return FALSE;
if (p1) {
if (wnd->wleft + ClientWidth(wnd)-1 >= wnd->textwidth)
return FALSE;
wnd->wleft++;
}
else
--wnd->wleft;
SendMessage(wnd, PAINT, 0, 0);
return TRUE;
case PAINT:
if (isVisible(wnd) && wnd->wlines) {
RECT rc;
int y;

if ((RECT *)p1 == NULL)
rc = SetRect(0, 0, ClientWidth(wnd)-1,
ClientHeight(wnd)-1);
else
rc = *(RECT *)p1;

for (y = RectTop(rc); y <= RectBottom(rc); y++) {
if (y < wnd->wlines-wnd->wtop)
WriteTextLine(wnd, &rc, y, FALSE);
else {
char line[SCREENWIDTH];
memset(line, ' ', sizeof line);
line[RectRight(rc)+1] = '\0';
SetStandardColor(wnd);
writeline(wnd, line+RectLeft(rc),
RectLeft(rc), y, FALSE);
}
}
if (TestAttribute(wnd, VSCROLLBAR)) {
int pagelen = wnd->wlines - ClientHeight(wnd);
int barlen = ClientHeight(wnd)-2;
int lines_tick;

if (pagelen < 1)
wnd->VScrollBox = 1;
else {
if (pagelen > barlen)
lines_tick = pagelen / barlen;
else
lines_tick = barlen / pagelen;
wnd->VScrollBox = 1 + (wnd->wtop / lines_tick);
if (wnd->VScrollBox > ClientHeight(wnd)-2 ||
wnd->wtop + ClientHeight(wnd) >= wnd->wlines)
wnd->VScrollBox = ClientHeight(wnd)-2;
}
SendMessage(wnd, BORDER, p1, 0);
}
if (TestAttribute(wnd, HSCROLLBAR)) {
int pagewidth = wnd->textwidth - ClientWidth(wnd);
int barlen = ClientWidth(wnd)-2;
int chars_tick;

if (pagewidth < 1)
wnd->HScrollBox = 1;
else {
if (pagewidth > barlen)
chars_tick = pagewidth / barlen;
else
chars_tick = barlen / pagewidth;
wnd->HScrollBox = 1 + (wnd->wleft / chars_tick);
if (wnd->HScrollBox > ClientWidth(wnd)-2 ||
wnd->wleft + ClientWidth(wnd) >= wnd->textwidth)
wnd->HScrollBox = ClientWidth(wnd)-2;
}
SendMessage(wnd, BORDER, p1, 0);
}
return FALSE;
}
break;
case CLOSE_WINDOW:
SendMessage(wnd, CLEARTEXT, 0, 0);
break;
default:
break;
}
return BaseWndProc(TEXTBOX, wnd, msg, p1, p2);
}

char *TextLine(WINDOW wnd, int selection)
{
char *cp = wnd->text;
if (selection == -1)
return NULL;
while (selection--) {
while (*cp != '\n')
cp++;
cp++;
}
return cp;
}

static char *GetTextLine(WINDOW wnd, int selection)
{
char *line;
int len = 0;
char *cp, *cp1;
cp = cp1 = TextLine(wnd, selection);
while (*cp && *cp != '\n') {
len++;
cp++;
}
line = malloc(len+6);
if (line != NULL) {
memmove(line, cp1, len);
line[len] = '\0';
}
return line;
}

void WriteTextLine(WINDOW wnd, RECT *rcc, int y, int reverse)
{
int len = 0;
int dif = 0;
char line[100];
RECT rc;
char *lp, *svlp;
int lnlen;
int i;
int trunc = FALSE;

lp = svlp = GetTextLine(wnd, wnd->wtop+y);
lnlen = LineLength(lp);

/* -------- insert block color change controls ------- */
if (BlockMarked(wnd)) {
int bbl = wnd->BlkBegLine;
int bel = wnd->BlkEndLine;
int bbc = wnd->BlkBegCol;
int bec = wnd->BlkEndCol;
int by = y+wnd->wtop;

if (bbl > bel) {
swap(bbl, bel);
swap(bbc, bec);
}
if (bbl == bel && bbc > bec)
swap(bbc, bec);

if (by >= bbl && by <= bel) {
/* ------ the block includes this line ----- */
int blkbeg = 0;
int blkend = lnlen;
if (!(by > bbl && by < bel)) {
/* --- the entire line is not in the block --- */
if (by == bbl)
/* ---- the block begins on this line ---- */
blkbeg = bbc;
if (by == bel)
/* ---- the block ends on this line ---- */
blkend = bec;
}
memmove(lp+blkend+1, lp+blkend, strlen(lp+blkend)+1);
lp[blkend] = RESETCOLOR;
memmove(lp+blkbeg+3, lp+blkbeg, strlen(lp+blkbeg)+1);
lp[blkbeg] = CHANGECOLOR;
SetReverseColor(wnd);
lp[blkbeg+1] = foreground | 0x80;
lp[blkbeg+2] = background | 0x80;
lnlen += 4;
}
}

for (i = 0; i < wnd->wleft+3; i++)
if (*(unsigned char *)(lp + i) == RESETCOLOR)
break;
if (i < wnd->wleft+3) {
if (wnd->wleft+4 > lnlen)
trunc = TRUE;
else
lp += 4;
}
else {
for (i = 0; i < wnd->wleft; i++) {
if (*(unsigned char *)(lp + i) == CHANGECOLOR) {
*(lp+wnd->wleft+2) = *(lp+i+2);
*(lp+wnd->wleft+1) = *(lp+i+1);
*(lp+wnd->wleft) = *(lp+i);
break;
}
}
}

if (!trunc) {
if (lnlen < wnd->wleft)
lnlen = 0;
else
lp += wnd->wleft;

if (rcc == NULL)
rc = SetRect(0, 0, ClientWidth(wnd)-1, ClientHeight(wnd)-1);
else
rc = *rcc;

if (y < rc.tp || y > rc.bt)
return;

if (lnlen > RectLeft(rc)) {
lp += RectLeft(rc);
lnlen = LineLength(lp);
len = min(lnlen, RectWidth(rc));
lnlen = LineLength(lp);
dif = strlen(lp) - lnlen;
len += dif;
if (len > 0)
strncpy(line, lp, len);
}
}

while (len < RectWidth(rc)+dif)
line[len++] = ' ';
line[len] = '\0';

dif = 0;
if (reverse) {
char *cp = line;
SetReverseColor(wnd);
while ((cp = strchr(cp, CHANGECOLOR)) != NULL) {
cp += 2;
*cp++ = background | 0x80;
}
if (*(unsigned char *)line == CHANGECOLOR)
dif = 3;
}
else
SetStandardColor(wnd);
writeline(wnd, line+dif, RectLeft(rc), y, FALSE);
if (svlp != NULL)
free(svlp);
}

void SetTextBlock(WINDOW wnd, int l1, int c1, int l2, int c2)
{
wnd->BlkBegLine = l1;
wnd->BlkBegCol = c1;
wnd->BlkEndLine = l2;
wnd->BlkEndCol = c2;
}



  3 Responses to “Category : Files from Magazines
Archive   : D-FLAT.ZIP
Filename : TEXTBOX.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/