diff options
Diffstat (limited to 'mdk-stage1/newt/textbox.c')
-rw-r--r-- | mdk-stage1/newt/textbox.c | 409 |
1 files changed, 0 insertions, 409 deletions
diff --git a/mdk-stage1/newt/textbox.c b/mdk-stage1/newt/textbox.c deleted file mode 100644 index 8eb4ae4db..000000000 --- a/mdk-stage1/newt/textbox.c +++ /dev/null @@ -1,409 +0,0 @@ -#include <ctype.h> -#include <slang.h> -#include <stdlib.h> -#include <string.h> - -#include "newt.h" -#include "newt_pr.h" - -struct textbox { - char ** lines; - int numLines; - int linesAlloced; - int doWrap; - newtComponent sb; - int topLine; - int textWidth; -}; - -static char * expandTabs(const char * text); -static void textboxDraw(newtComponent co); -static void addLine(newtComponent co, const char * s, int len); -static void doReflow(const char * text, char ** resultPtr, int width, - int * badness, int * heightPtr); -static struct eventResult textboxEvent(newtComponent c, - struct event ev); -static void textboxDestroy(newtComponent co); -static void textboxPlace(newtComponent co, int newLeft, int newTop); -static void textboxMapped(newtComponent co, int isMapped); - -static struct componentOps textboxOps = { - textboxDraw, - textboxEvent, - textboxDestroy, - textboxPlace, - textboxMapped, -} ; - -static void textboxMapped(newtComponent co, int isMapped) { - struct textbox * tb = co->data; - - co->isMapped = isMapped; - if (tb->sb) - tb->sb->ops->mapped(tb->sb, isMapped); -} - -static void textboxPlace(newtComponent co, int newLeft, int newTop) { - struct textbox * tb = co->data; - - co->top = newTop; - co->left = newLeft; - - if (tb->sb) - tb->sb->ops->place(tb->sb, co->left + co->width - 1, co->top); -} - -void newtTextboxSetHeight(newtComponent co, int height) { - co->height = height; -} - -int newtTextboxGetNumLines(newtComponent co) { - struct textbox * tb = co->data; - - return (tb->numLines); -} - -newtComponent newtTextboxReflowed(int left, int top, char * text, int width, - int flexDown, int flexUp, int flags __attribute__ ((unused))) { - newtComponent co; - char * reflowedText; - int actWidth, actHeight; - - reflowedText = newtReflowText(text, width, flexDown, flexUp, - &actWidth, &actHeight); - - co = newtTextbox(left, top, actWidth, actHeight, NEWT_FLAG_WRAP); - newtTextboxSetText(co, reflowedText); - free(reflowedText); - - return co; -} - -newtComponent newtTextbox(int left, int top, int width, int height, int flags) { - newtComponent co; - struct textbox * tb; - - co = malloc(sizeof(*co)); - tb = malloc(sizeof(*tb)); - co->data = tb; - - co->ops = &textboxOps; - - co->height = height; - co->top = top; - co->left = left; - co->takesFocus = 0; - co->width = width; - - tb->doWrap = flags & NEWT_FLAG_WRAP; - tb->numLines = 0; - tb->linesAlloced = 0; - tb->lines = NULL; - tb->topLine = 0; - tb->textWidth = width; - - if (flags & NEWT_FLAG_SCROLL) { - co->width += 2; - tb->sb = newtVerticalScrollbar(co->left + co->width - 1, co->top, - co->height, COLORSET_TEXTBOX, COLORSET_TEXTBOX); - } else { - tb->sb = NULL; - } - - return co; -} - -static char * expandTabs(const char * text) { - int bufAlloced = strlen(text) + 40; - char * buf, * dest; - const char * src; - int bufUsed = 0; - int linePos = 0; - int i; - - buf = malloc(bufAlloced + 1); - for (src = text, dest = buf; *src; src++) { - if ((bufUsed + 10) > bufAlloced) { - bufAlloced += strlen(text) / 2; - buf = realloc(buf, bufAlloced + 1); - dest = buf + bufUsed; - } - if (*src == '\t') { - i = 8 - (linePos & 8); - memset(dest, ' ', i); - dest += i, bufUsed += i, linePos += i; - } else { - if (*src == '\n') - linePos = 0; - else - linePos++; - - *dest++ = *src; - bufUsed++; - } - } - - *dest = '\0'; - return buf; -} - -#define iseuckanji(c) (0xa1 <= (unsigned char)(c&0xff) && (unsigned char)(c&0xff) <= 0xfe) - -static void doReflow(const char * text, char ** resultPtr, int width, - int * badness, int * heightPtr) { - char * result = NULL; - const char * chptr, * end; - int i; - int howbad = 0; - int height = 0; - int kanji = 0; - - if (resultPtr) { - /* XXX I think this will work */ - result = malloc(strlen(text) + (strlen(text) / width) + 50); - *result = '\0'; - } - - while (*text) { - kanji = 0; - end = strchr(text, '\n'); - if (!end) - end = text + strlen(text); - - while (*text && text < end) { - if (end - text < width) { - if (result) { - strncat(result, text, end - text); - strcat(result, "\n"); - height++; - } - - if (end - text < (width / 2)) - howbad += ((width / 2) - (end - text)) / 2; - text = end; - if (*text) text++; - } else { - chptr = text; - kanji = 0; - for ( i = 0; i < width - 1; i++ ) { - if ( !iseuckanji(*chptr)) { - kanji = 0; - } else if ( kanji == 1 ) { - kanji = 2; - } else { - kanji = 1; - } - chptr++; - } - if (kanji == 0) { - while (chptr > text && !isspace(*chptr)) chptr--; - while (chptr > text && isspace(*chptr)) chptr--; - chptr++; - } - - if (chptr-text == 1 && !isspace(*chptr)) - chptr = text + width - 1; - - if (chptr > text) - howbad += width - (chptr - text) + 1; - if (result) { - if (kanji == 1) { - strncat(result, text, chptr - text + 1); - chptr++; - kanji = 0; - } else { - strncat(result, text, chptr - text); - } - strcat(result, "\n"); - height++; - } - - if (isspace(*chptr)) - text = chptr + 1; - else - text = chptr; - while (isspace(*text)) text++; - } - } - } - -// if (result) printf("result: %s\n", result); - - if (badness) *badness = howbad; - if (resultPtr) *resultPtr = result; - if (heightPtr) *heightPtr = height; -} - -char * newtReflowText(char * text, int width, int flexDown, int flexUp, - int * actualWidth, int * actualHeight) { - int min, max; - int i; - char * result; - int minbad, minbadwidth, howbad; - char * expandedText; - - expandedText = expandTabs(text); - - if (flexDown || flexUp) { - min = width - flexDown; - max = width + flexUp; - - minbad = -1; - minbadwidth = width; - - for (i = min; i <= max; i++) { - doReflow(expandedText, NULL, i, &howbad, NULL); - - if (minbad == -1 || howbad < minbad) { - minbad = howbad; - minbadwidth = i; - } - } - - width = minbadwidth; - } - - doReflow(expandedText, &result, width, NULL, actualHeight); - free(expandedText); - if (actualWidth) *actualWidth = width; - return result; -} - -void newtTextboxSetText(newtComponent co, const char * text) { - const char * start, * end; - struct textbox * tb = co->data; - char * reflowed, * expanded; - int badness, height; - - if (tb->lines) { - free(tb->lines); - tb->linesAlloced = tb->numLines = 0; - } - - expanded = expandTabs(text); - - if (tb->doWrap) { - doReflow(expanded, &reflowed, tb->textWidth, &badness, &height); - free(expanded); - expanded = reflowed; - } - - for (start = expanded; *start; start++) - if (*start == '\n') tb->linesAlloced++; - - /* This ++ leaves room for an ending line w/o a \n */ - tb->linesAlloced++; - tb->lines = malloc(sizeof(char *) * tb->linesAlloced); - - start = expanded; - while ((end = strchr(start, '\n'))) { - addLine(co, start, end - start); - start = end + 1; - } - - if (*start) - addLine(co, start, strlen(start)); - - free(expanded); -} - -/* This assumes the buffer is allocated properly! */ -static void addLine(newtComponent co, const char * s, int len) { - struct textbox * tb = co->data; - - if (len > tb->textWidth) len = tb->textWidth; - - tb->lines[tb->numLines] = malloc(tb->textWidth + 1); - memset(tb->lines[tb->numLines], ' ', tb->textWidth); - memcpy(tb->lines[tb->numLines], s, len); - tb->lines[tb->numLines++][tb->textWidth] = '\0'; -} - -static void textboxDraw(newtComponent c) { - int i; - struct textbox * tb = c->data; - int size; - - if (tb->sb) { - size = tb->numLines - c->height; - newtScrollbarSet(tb->sb, tb->topLine, size ? size : 0); - tb->sb->ops->draw(tb->sb); - } - - SLsmg_set_color(NEWT_COLORSET_TEXTBOX); - - for (i = 0; (i + tb->topLine) < tb->numLines && i < c->height; i++) { - newtGotorc(c->top + i, c->left); - SLsmg_write_string(tb->lines[i + tb->topLine]); - } -} - -static struct eventResult textboxEvent(newtComponent co, - struct event ev) { - struct textbox * tb = co->data; - struct eventResult er; - - er.result = ER_IGNORED; - - if (ev.when == EV_EARLY && ev.event == EV_KEYPRESS && tb->sb) { - switch (ev.u.key) { - case NEWT_KEY_UP: - if (tb->topLine) tb->topLine--; - textboxDraw(co); - er.result = ER_SWALLOWED; - break; - - case NEWT_KEY_DOWN: - if (tb->topLine < (tb->numLines - co->height)) tb->topLine++; - textboxDraw(co); - er.result = ER_SWALLOWED; - break; - - case NEWT_KEY_PGDN: - tb->topLine += co->height; - if (tb->topLine > (tb->numLines - co->height)) { - tb->topLine = tb->numLines - co->height; - if (tb->topLine < 0) tb->topLine = 0; - } - textboxDraw(co); - er.result = ER_SWALLOWED; - break; - - case NEWT_KEY_PGUP: - tb->topLine -= co->height; - if (tb->topLine < 0) tb->topLine = 0; - textboxDraw(co); - er.result = ER_SWALLOWED; - break; - } - } - if (ev.when == EV_EARLY && ev.event == EV_MOUSE && tb->sb) { - /* Top scroll arrow */ - if (ev.u.mouse.x == co->width && ev.u.mouse.y == co->top) { - if (tb->topLine) tb->topLine--; - textboxDraw(co); - - er.result = ER_SWALLOWED; - } - /* Bottom scroll arrow */ - if (ev.u.mouse.x == co->width && - ev.u.mouse.y == co->top + co->height - 1) { - if (tb->topLine < (tb->numLines - co->height)) tb->topLine++; - textboxDraw(co); - - er.result = ER_SWALLOWED; - } - } - return er; -} - -static void textboxDestroy(newtComponent co) { - int i; - struct textbox * tb = co->data; - - for (i = 0; i < tb->numLines; i++) - free(tb->lines[i]); - free(tb->lines); - free(tb); - free(co); -} |