|
Packit |
4d380f |
|
|
Packit |
4d380f |
#include <ctype.h>
|
|
Packit |
4d380f |
#include <slang.h>
|
|
Packit |
4d380f |
#include <stdlib.h>
|
|
Packit |
4d380f |
#include <string.h>
|
|
Packit |
4d380f |
#include <wchar.h>
|
|
Packit |
4d380f |
#include <wctype.h>
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
#include "newt.h"
|
|
Packit |
4d380f |
#include "newt_pr.h"
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
struct textbox {
|
|
Packit |
4d380f |
char ** lines;
|
|
Packit |
4d380f |
int numLines;
|
|
Packit |
4d380f |
int linesAlloced;
|
|
Packit |
4d380f |
int doWrap;
|
|
Packit |
4d380f |
newtComponent sb;
|
|
Packit |
4d380f |
int topLine;
|
|
Packit |
4d380f |
int textWidth;
|
|
Packit |
4d380f |
int isActive;
|
|
Packit |
4d380f |
int cs;
|
|
Packit |
4d380f |
int csActive;
|
|
Packit |
4d380f |
};
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static char * expandTabs(const char * text);
|
|
Packit |
4d380f |
static void textboxDraw(newtComponent co);
|
|
Packit |
4d380f |
static void addLine(newtComponent co, const char * s, int len);
|
|
Packit |
4d380f |
static void doReflow(const char * text, char ** resultPtr, int width,
|
|
Packit |
4d380f |
int * badness, int * heightPtr);
|
|
Packit |
4d380f |
static struct eventResult textboxEvent(newtComponent c,
|
|
Packit |
4d380f |
struct event ev);
|
|
Packit |
4d380f |
static void textboxDestroy(newtComponent co);
|
|
Packit |
4d380f |
static void textboxPlace(newtComponent co, int newLeft, int newTop);
|
|
Packit |
4d380f |
static void textboxMapped(newtComponent co, int isMapped);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static struct componentOps textboxOps = {
|
|
Packit |
4d380f |
textboxDraw,
|
|
Packit |
4d380f |
textboxEvent,
|
|
Packit |
4d380f |
textboxDestroy,
|
|
Packit |
4d380f |
textboxPlace,
|
|
Packit |
4d380f |
textboxMapped,
|
|
Packit |
4d380f |
} ;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static void textboxMapped(newtComponent co, int isMapped) {
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
co->isMapped = isMapped;
|
|
Packit |
4d380f |
if (tb->sb) {
|
|
Packit |
4d380f |
tb->sb->ops->mapped(tb->sb, isMapped);
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static void textboxPlace(newtComponent co, int newLeft, int newTop) {
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
co->top = newTop;
|
|
Packit |
4d380f |
co->left = newLeft;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (tb->sb) {
|
|
Packit |
4d380f |
tb->sb->ops->place(tb->sb, co->left + co->width - 1, co->top);
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
void newtTextboxSetHeight(newtComponent co, int height) {
|
|
Packit |
4d380f |
co->height = height;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
int newtTextboxGetNumLines(newtComponent co) {
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
return (tb->numLines);
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
newtComponent newtTextboxReflowed(int left, int top, char * text, int width,
|
|
Packit |
4d380f |
int flexDown, int flexUp, int flags) {
|
|
Packit |
4d380f |
newtComponent co;
|
|
Packit |
4d380f |
char * reflowedText;
|
|
Packit |
4d380f |
int actWidth, actHeight;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
reflowedText = newtReflowText(text, width, flexDown, flexUp,
|
|
Packit |
4d380f |
&actWidth, &actHeight);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
co = newtTextbox(left, top, actWidth, actHeight, NEWT_FLAG_WRAP);
|
|
Packit |
4d380f |
newtTextboxSetText(co, reflowedText);
|
|
Packit |
4d380f |
free(reflowedText);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
return co;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
newtComponent newtTextbox(int left, int top, int width, int height, int flags) {
|
|
Packit |
4d380f |
newtComponent co;
|
|
Packit |
4d380f |
struct textbox * tb;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
co = malloc(sizeof(*co));
|
|
Packit |
4d380f |
tb = malloc(sizeof(*tb));
|
|
Packit |
4d380f |
co->data = tb;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (width < 1)
|
|
Packit |
4d380f |
width = 1;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
co->ops = &textboxOps;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
co->isMapped = 0;
|
|
Packit |
4d380f |
co->height = height;
|
|
Packit |
4d380f |
co->top = top;
|
|
Packit |
4d380f |
co->left = left;
|
|
Packit |
4d380f |
co->takesFocus = 0;
|
|
Packit |
4d380f |
co->width = width;
|
|
Packit |
4d380f |
co->destroyCallback = NULL;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
tb->doWrap = flags & NEWT_FLAG_WRAP;
|
|
Packit |
4d380f |
tb->numLines = 0;
|
|
Packit |
4d380f |
tb->linesAlloced = 0;
|
|
Packit |
4d380f |
tb->lines = NULL;
|
|
Packit |
4d380f |
tb->topLine = 0;
|
|
Packit |
4d380f |
tb->textWidth = width;
|
|
Packit |
4d380f |
tb->isActive = 0;
|
|
Packit |
4d380f |
tb->cs = COLORSET_TEXTBOX;
|
|
Packit |
4d380f |
tb->csActive = COLORSET_ACTTEXTBOX;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (flags & NEWT_FLAG_SCROLL) {
|
|
Packit |
4d380f |
co->width += 2;
|
|
Packit |
4d380f |
tb->sb = newtVerticalScrollbar(co->left + co->width - 1, co->top,
|
|
Packit |
4d380f |
co->height, tb->cs, tb->cs);
|
|
Packit |
4d380f |
co->takesFocus = 1;
|
|
Packit |
4d380f |
} else {
|
|
Packit |
4d380f |
tb->sb = NULL;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
return co;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
void newtTextboxSetColors(newtComponent co, int normal, int active) {
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
tb->cs = normal;
|
|
Packit |
4d380f |
tb->csActive = active;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static char * expandTabs(const char * text) {
|
|
Packit |
4d380f |
int bufAlloced = strlen(text) + 40;
|
|
Packit |
4d380f |
char * buf, * dest;
|
|
Packit |
4d380f |
const char * src;
|
|
Packit |
4d380f |
int bufUsed = 0;
|
|
Packit |
4d380f |
int linePos = 0;
|
|
Packit |
4d380f |
int i;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
buf = malloc(bufAlloced + 1);
|
|
Packit |
4d380f |
for (src = text, dest = buf; *src; src++) {
|
|
Packit |
4d380f |
if ((bufUsed + 10) > bufAlloced) {
|
|
Packit |
4d380f |
bufAlloced += strlen(text) / 2;
|
|
Packit |
4d380f |
buf = realloc(buf, bufAlloced + 1);
|
|
Packit |
4d380f |
dest = buf + bufUsed;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
if (*src == '\t') {
|
|
Packit |
4d380f |
i = 8 - (linePos & 8);
|
|
Packit |
4d380f |
memset(dest, ' ', i);
|
|
Packit |
4d380f |
dest += i, bufUsed += i, linePos += i;
|
|
Packit |
4d380f |
} else {
|
|
Packit |
4d380f |
if (*src == '\n')
|
|
Packit |
4d380f |
linePos = 0;
|
|
Packit |
4d380f |
else
|
|
Packit |
4d380f |
linePos++;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
*dest++ = *src;
|
|
Packit |
4d380f |
bufUsed++;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
*dest = '\0';
|
|
Packit |
4d380f |
return buf;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static void doReflow(const char * text, char ** resultPtr, int width,
|
|
Packit |
4d380f |
int * badness, int * heightPtr) {
|
|
Packit |
4d380f |
char * result = NULL;
|
|
Packit |
4d380f |
const char * chptr, * end;
|
|
Packit |
4d380f |
int i;
|
|
Packit |
4d380f |
int howbad = 0;
|
|
Packit |
4d380f |
int height = 0;
|
|
Packit |
4d380f |
wchar_t tmp;
|
|
Packit |
4d380f |
mbstate_t ps;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (resultPtr) {
|
|
Packit |
4d380f |
if (width > 1) {
|
|
Packit |
4d380f |
/* use width - 1 for double width characters
|
|
Packit |
4d380f |
that won't fit at end of line */
|
|
Packit |
4d380f |
result = malloc(strlen(text) + (strlen(text) / (width - 1)) + 2);
|
|
Packit |
4d380f |
} else
|
|
Packit |
4d380f |
result = malloc(strlen(text) * 2 + 2);
|
|
Packit |
4d380f |
*resultPtr = result;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
memset(&ps,0,sizeof(mbstate_t));
|
|
Packit |
4d380f |
while (*text) {
|
|
Packit |
4d380f |
end = strchr(text, '\n');
|
|
Packit |
4d380f |
if (!end)
|
|
Packit |
4d380f |
end = text + strlen(text);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
while (*text && text <= end) {
|
|
Packit |
4d380f |
int len;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
len = wstrlen(text, end - text);
|
|
Packit |
4d380f |
if (len <= width) {
|
|
Packit |
4d380f |
if (result) {
|
|
Packit |
4d380f |
memcpy(result, text, end - text);
|
|
Packit |
4d380f |
result += end - text;
|
|
Packit |
4d380f |
*result++ = '\n';
|
|
Packit |
4d380f |
height++;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (len < (width / 2)) {
|
|
Packit |
4d380f |
#ifdef DEBUG_WRAP
|
|
Packit |
4d380f |
fprintf(stderr,"adding %d\n",((width / 2) - (len)) / 2);
|
|
Packit |
4d380f |
#endif
|
|
Packit |
4d380f |
howbad += ((width / 2) - (len)) / 2;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
text = end;
|
|
Packit |
4d380f |
if (*text) text++;
|
|
Packit |
4d380f |
} else {
|
|
Packit |
4d380f |
const char *spcptr = NULL;
|
|
Packit |
4d380f |
int spc = 0, w2 = 0, x, w;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
chptr = text;
|
|
Packit |
4d380f |
i = 0;
|
|
Packit |
4d380f |
while (1) {
|
|
Packit |
4d380f |
if ((x=mbrtowc(&tmp,chptr,end-chptr,&ps))<=0)
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
if (spc && !iswspace(tmp))
|
|
Packit |
4d380f |
spc = 0;
|
|
Packit |
4d380f |
else if (!spc && iswspace(tmp)) {
|
|
Packit |
4d380f |
spc = 1;
|
|
Packit |
4d380f |
spcptr = chptr;
|
|
Packit |
4d380f |
w2 = i;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
w = wcwidth(tmp);
|
|
Packit |
4d380f |
if (w < 0)
|
|
Packit |
4d380f |
w = 0;
|
|
Packit |
4d380f |
if (i && w + i > width)
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
chptr += x;
|
|
Packit |
4d380f |
i += w;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
howbad += width - w2 + 1;
|
|
Packit |
4d380f |
#ifdef DEBUG_WRAP
|
|
Packit |
4d380f |
fprintf(stderr,"adding %d\n",width - w2 + 1, chptr);
|
|
Packit |
4d380f |
#endif
|
|
Packit |
4d380f |
if (spcptr) chptr = spcptr;
|
|
Packit |
4d380f |
if (result) {
|
|
Packit |
4d380f |
memcpy(result, text, chptr - text);
|
|
Packit |
4d380f |
result += chptr - text;
|
|
Packit |
4d380f |
*result++ = '\n';
|
|
Packit |
4d380f |
height++;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
text = chptr;
|
|
Packit |
4d380f |
while (1) {
|
|
Packit |
4d380f |
if ((x=mbrtowc(&tmp,text,end-text,NULL))<=0)
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
if (!iswspace(tmp)) break;
|
|
Packit |
4d380f |
text += x;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (result)
|
|
Packit |
4d380f |
*result = '\0';
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (badness) *badness = howbad;
|
|
Packit |
4d380f |
if (heightPtr) *heightPtr = height;
|
|
Packit |
4d380f |
#ifdef DEBUG_WRAP
|
|
Packit |
4d380f |
fprintf(stderr, "width %d, badness %d, height %d\n",width, howbad, height);
|
|
Packit |
4d380f |
#endif
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
char * newtReflowText(char * text, int width, int flexDown, int flexUp,
|
|
Packit |
4d380f |
int * actualWidth, int * actualHeight) {
|
|
Packit |
4d380f |
int min, max;
|
|
Packit |
4d380f |
int i;
|
|
Packit |
4d380f |
char * result;
|
|
Packit |
4d380f |
int minbad, minbadwidth, howbad;
|
|
Packit |
4d380f |
char * expandedText;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (width < 1)
|
|
Packit |
4d380f |
width = 1;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
expandedText = expandTabs(text);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (flexDown || flexUp) {
|
|
Packit |
4d380f |
min = width - flexDown;
|
|
Packit |
4d380f |
max = width + flexUp;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
minbad = -1;
|
|
Packit |
4d380f |
minbadwidth = width;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
for (i = min; i >= 1 && i <= max; i++) {
|
|
Packit |
4d380f |
doReflow(expandedText, NULL, i, &howbad, NULL);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (minbad == -1 || howbad < minbad) {
|
|
Packit |
4d380f |
minbad = howbad;
|
|
Packit |
4d380f |
minbadwidth = i;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
width = minbadwidth;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
doReflow(expandedText, &result, width, NULL, actualHeight);
|
|
Packit |
4d380f |
free(expandedText);
|
|
Packit |
4d380f |
if (actualWidth) *actualWidth = width;
|
|
Packit |
4d380f |
return result;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
void newtTextboxSetText(newtComponent co, const char * text) {
|
|
Packit |
4d380f |
const char * start, * end;
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
char * reflowed, * expanded;
|
|
Packit |
4d380f |
int badness, height;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (tb->lines) {
|
|
Packit |
4d380f |
int i;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
for (i = 0; i < tb->numLines; i++)
|
|
Packit |
4d380f |
free(tb->lines[i]);
|
|
Packit |
4d380f |
free(tb->lines);
|
|
Packit |
4d380f |
tb->linesAlloced = tb->numLines = tb->topLine = 0;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
expanded = expandTabs(text);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (tb->doWrap) {
|
|
Packit |
4d380f |
doReflow(expanded, &reflowed, tb->textWidth, &badness, &height);
|
|
Packit |
4d380f |
free(expanded);
|
|
Packit |
4d380f |
expanded = reflowed;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
for (start = expanded; *start; start++)
|
|
Packit |
4d380f |
if (*start == '\n') tb->linesAlloced++;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
/* This ++ leaves room for an ending line w/o a \n */
|
|
Packit |
4d380f |
tb->linesAlloced++;
|
|
Packit |
4d380f |
tb->lines = malloc(sizeof(char *) * tb->linesAlloced);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
start = expanded;
|
|
Packit |
4d380f |
while ((end = strchr(start, '\n'))) {
|
|
Packit |
4d380f |
addLine(co, start, end - start);
|
|
Packit |
4d380f |
start = end + 1;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (*start)
|
|
Packit |
4d380f |
addLine(co, start, strlen(start));
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
free(expanded);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
newtTrashScreen();
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
/* This assumes the buffer is allocated properly! */
|
|
Packit |
4d380f |
static void addLine(newtComponent co, const char * s, int len) {
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
while (wstrlen(s,len) > tb->textWidth) {
|
|
Packit |
4d380f |
len--;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
tb->lines[tb->numLines] = malloc(len + 1);
|
|
Packit |
4d380f |
memcpy(tb->lines[tb->numLines], s, len);
|
|
Packit |
4d380f |
tb->lines[tb->numLines++][len] = '\0';
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static void textboxDraw(newtComponent c) {
|
|
Packit |
4d380f |
int i;
|
|
Packit |
4d380f |
struct textbox * tb = c->data;
|
|
Packit |
4d380f |
int size;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (!c->isMapped)
|
|
Packit |
4d380f |
return;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (tb->sb) {
|
|
Packit |
4d380f |
size = tb->numLines - c->height;
|
|
Packit |
4d380f |
newtScrollbarSet(tb->sb, tb->topLine, size ? size : 0);
|
|
Packit |
4d380f |
newtScrollbarSetColors(tb->sb, tb->isActive ? tb->csActive :
|
|
Packit |
4d380f |
tb->cs, tb->cs);
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
SLsmg_set_color(tb->cs);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
for (i = 0; (i + tb->topLine) < tb->numLines && i < c->height; i++) {
|
|
Packit |
4d380f |
newtGotorc(c->top + i, c->left);
|
|
Packit |
4d380f |
SLsmg_write_nstring(tb->lines[i + tb->topLine], tb->textWidth);
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
/* put cursor at beginning of text for better accessibility */
|
|
Packit |
4d380f |
newtGotorc(c->top, c->left);
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static struct eventResult textboxEvent(newtComponent co,
|
|
Packit |
4d380f |
struct event ev) {
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
struct eventResult er;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
er.result = ER_IGNORED;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (!tb->sb || ev.when == EV_EARLY || ev.when == EV_LATE)
|
|
Packit |
4d380f |
return er;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
switch(ev.event) {
|
|
Packit |
4d380f |
case EV_KEYPRESS:
|
|
Packit |
4d380f |
newtTrashScreen();
|
|
Packit |
4d380f |
switch (ev.u.key) {
|
|
Packit |
4d380f |
case NEWT_KEY_UP:
|
|
Packit |
4d380f |
if (tb->topLine) tb->topLine--;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
case NEWT_KEY_DOWN:
|
|
Packit |
4d380f |
if (tb->topLine < (tb->numLines - co->height)) tb->topLine++;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
case NEWT_KEY_PGDN:
|
|
Packit |
4d380f |
tb->topLine += co->height;
|
|
Packit |
4d380f |
if (tb->topLine > (tb->numLines - co->height)) {
|
|
Packit |
4d380f |
tb->topLine = tb->numLines - co->height;
|
|
Packit |
4d380f |
if (tb->topLine < 0) tb->topLine = 0;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
case NEWT_KEY_PGUP:
|
|
Packit |
4d380f |
tb->topLine -= co->height;
|
|
Packit |
4d380f |
if (tb->topLine < 0) tb->topLine = 0;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
case EV_MOUSE:
|
|
Packit |
4d380f |
/* Top scroll arrow */
|
|
Packit |
4d380f |
if (ev.u.mouse.x == co->width && ev.u.mouse.y == co->top) {
|
|
Packit |
4d380f |
if (tb->topLine) tb->topLine--;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
/* Bottom scroll arrow */
|
|
Packit |
4d380f |
if (ev.u.mouse.x == co->width &&
|
|
Packit |
4d380f |
ev.u.mouse.y == co->top + co->height - 1) {
|
|
Packit |
4d380f |
if (tb->topLine < (tb->numLines - co->height)) tb->topLine++;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
case EV_FOCUS:
|
|
Packit |
4d380f |
tb->isActive = 1;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
case EV_UNFOCUS:
|
|
Packit |
4d380f |
tb->isActive = 0;
|
|
Packit |
4d380f |
textboxDraw(co);
|
|
Packit |
4d380f |
er.result = ER_SWALLOWED;
|
|
Packit |
4d380f |
break;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
return er;
|
|
Packit |
4d380f |
}
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
static void textboxDestroy(newtComponent co) {
|
|
Packit |
4d380f |
int i;
|
|
Packit |
4d380f |
struct textbox * tb = co->data;
|
|
Packit |
4d380f |
|
|
Packit |
4d380f |
if (tb->sb)
|
|
Packit |
4d380f |
tb->sb->ops->destroy(tb->sb);
|
|
Packit |
4d380f |
for (i = 0; i < tb->numLines; i++)
|
|
Packit |
4d380f |
free(tb->lines[i]);
|
|
Packit |
4d380f |
free(tb->lines);
|
|
Packit |
4d380f |
free(tb);
|
|
Packit |
4d380f |
free(co);
|
|
Packit |
4d380f |
}
|