]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
Initial revision
authorewt <ewt>
Wed, 17 Apr 1996 00:42:02 +0000 (00:42 +0000)
committerewt <ewt>
Wed, 17 Apr 1996 00:42:02 +0000 (00:42 +0000)
textbox.c [new file with mode: 0644]

diff --git a/textbox.c b/textbox.c
new file mode 100644 (file)
index 0000000..504ebbe
--- /dev/null
+++ b/textbox.c
@@ -0,0 +1,188 @@
+#include <ctype.h>
+#include <slang/slang.h>
+#include <stdlib.h>
+
+#include "newt.h"
+#include "newt_pr.h"
+
+struct textbox {
+    char ** lines;
+    int numLines;
+    int linesAlloced;
+    int doWrap;
+    newtComponent sb;
+    int topLine;
+};
+
+static void addLine(newtComponent co, const char * s, int len);
+static void textboxDraw(newtComponent co);
+static void addShortLine(newtComponent co, const char * s, int len);
+static struct eventResult textboxEvent(struct newtComponent * c, 
+                                     struct event ev);
+static void textboxDestroy(newtComponent co);
+
+static struct componentOps textboxOps = {
+    textboxDraw,
+    textboxEvent,
+    textboxDestroy,
+} ;
+
+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;
+
+    tb->doWrap = flags & NEWT_TEXTBOX_WRAP;
+    tb->numLines = 0;
+    tb->linesAlloced = 0;
+    tb->lines = NULL;
+    tb->topLine = 0;
+
+    if (flags & NEWT_TEXTBOX_SCROLL) {
+       co->width = width - 2;
+       tb->sb = newtVerticalScrollbar(co->left + co->width + 1, co->top, 
+                          co->height, COLORSET_TEXTBOX, COLORSET_TEXTBOX);
+    } else {
+       co->width = width;
+       tb->sb = NULL;
+    }
+
+    return co;
+}
+
+void newtTextboxSetText(newtComponent co, const char * text) {
+    const char * start, * end;
+    struct textbox * tb = co->data;
+
+    if (tb->lines) {
+       free(tb->lines);
+       tb->numLines = 0;
+    }
+
+    tb->linesAlloced = 10;
+    tb->lines = malloc(sizeof(char *) * 10);
+
+    start = text;
+    while ((end = strchr(start, '\n'))) {
+       addLine(co, start, end - start);
+       start = end + 1;
+    }
+
+    if (*start)
+       addLine(co, start, -1);
+}
+
+static void addLine(newtComponent co, const char * s, int origlen) {
+    const char * start, * end;
+    int len;
+    struct textbox * tb = co->data;
+
+    if (origlen < 0) origlen = strlen(s);
+    len = origlen;
+
+    if (!tb->doWrap || len <= co->width) {
+       addShortLine(co, s, len);
+    } else {
+       /* word wrap */
+
+       start = s;
+       while (len > co->width) {
+           end = start + co->width - 1;
+           while (end > start && !isspace(*end)) end--;
+
+           if (end == start)
+               end = start + co->width - 1;
+
+           addShortLine(co, start, end - start);
+       
+           start = end + 1;
+           while (isspace(*start) && *start) start++;
+
+           len = origlen - (start - s);
+       }       
+
+       if (*start)
+           addShortLine(co, start, len);
+    }
+}
+
+static void addShortLine(newtComponent co, const char * s, int len) {
+    struct textbox * tb = co->data;
+
+    if (tb->linesAlloced == tb->numLines) {
+       tb->linesAlloced += 10;
+       tb->lines = realloc(tb->lines, (sizeof(char *) * tb->linesAlloced));
+    }
+
+    if (len > co->width) len = co->width;
+
+    tb->lines[tb->numLines] = malloc(co->width + 1);
+    strncpy(tb->lines[tb->numLines], s, len);
+
+    while (len < co->width)  tb->lines[tb->numLines][len++] = ' ';
+    tb->lines[tb->numLines++][len] = '\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);
+    }
+   
+    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(struct 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;
+       }
+    }
+
+    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);
+}