From 8f52cd471df10b5de73d22fa5a38c9d7d7761145 Mon Sep 17 00:00:00 2001 From: ewt Date: Fri, 6 Mar 1998 14:33:04 +0000 Subject: [PATCH] 1) got scrollbars working w/ gridded text widgets 2) added mapped method to components (mandatory) 3) made placed component method mandatory 4) added newtGrid[VH]CloseStacked() 5) added newtGridBasicWindow() 6) made newtGrid[VH]Stacked() not set GROWX flag for any fields --- button.c | 8 ++++-- checkbox.c | 3 +- entry.c | 6 ++-- form.c | 65 ++++++++++++++++++++++++++++++++----------- grid.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-------- label.c | 3 +- listbox.c | 24 +++++++++++----- newt.c | 9 ++++++ newt.h | 6 ++++ newt_pr.h | 5 +++- scale.c | 3 +- scrollbar.c | 3 +- textbox.c | 45 ++++++++++++++++++++++-------- windows.c | 13 ++++----- 14 files changed, 210 insertions(+), 63 deletions(-) diff --git a/button.c b/button.c index bbfeb7f..03f68a5 100644 --- a/button.c +++ b/button.c @@ -18,13 +18,14 @@ static void buttonDraw(newtComponent c); static void buttonDestroy(newtComponent co); static struct eventResult buttonEvent(newtComponent c, struct event ev); -static void buttonPlace(newtComponent co); +static void buttonPlace(newtComponent co, int newLeft, int newTop); static struct componentOps buttonOps = { buttonDraw, buttonEvent, buttonDestroy, buttonPlace, + newtDefaultMappedHandler, } ; static newtComponent createButton(int left, int row, const char * text, int compact) { @@ -74,9 +75,12 @@ static void buttonDestroy(newtComponent co) { free(co); } -static void buttonPlace(newtComponent co) { +static void buttonPlace(newtComponent co, int newLeft, int newTop) { struct button * bu = co->data; + co->top = newTop; + co->left = newLeft; + newtGotorc(co->top, co->left); bu->bgColor = (SLsmg_char_at() >> 8) & 0xFF; } diff --git a/checkbox.c b/checkbox.c index 1c798af..bb2cb55 100644 --- a/checkbox.c +++ b/checkbox.c @@ -30,7 +30,8 @@ static struct componentOps cbOps = { cbDraw, cbEvent, cbDestroy, - NULL, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, } ; newtComponent newtListitem(int left, int top, const char * text, int isDefault, diff --git a/entry.c b/entry.c index 407266e..aa83662 100644 --- a/entry.c +++ b/entry.c @@ -27,7 +27,8 @@ static struct componentOps entryOps = { entryDraw, entryEvent, entryDestroy, - NULL, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, } ; void newtEntrySet(newtComponent co, const char * value, int cursorAtEnd) { @@ -64,6 +65,7 @@ newtComponent newtEntry(int left, int top, const char * initialValue, int width, co->left = left; co->height = 1; co->width = width; + co->isMapped = 0; co->callback = NULL; co->ops = &entryOps; @@ -106,7 +108,7 @@ static void entryDraw(newtComponent co) { char * chptr; int len; - if (co->top == -1) return; + if (!co->isMapped) return; if (en->flags & NEWT_FLAG_DISABLED) SLsmg_set_color(NEWT_COLORSET_DISENTRY); diff --git a/form.c b/form.c index a5585e8..9a62fe8 100644 --- a/form.c +++ b/form.c @@ -39,11 +39,15 @@ struct form { static void gotoComponent(struct form * form, int newComp); static struct eventResult formEvent(newtComponent co, struct event ev); static struct eventResult sendEvent(newtComponent comp, struct event ev); +static void formPlace(newtComponent co, int left, int top); -static struct componentOps formOps = { +/* this isn't static as grid.c tests against it to find forms */ +struct componentOps formOps = { newtDrawForm, formEvent, newtFormDestroy, + formPlace, + newtDefaultMappedHandler, } ; static inline int componentFits(newtComponent co, int compNum) { @@ -70,7 +74,7 @@ newtComponent newtForm(newtComponent vertBar, const char * help, int flags) { co->left = -1; co->isMapped = 0; - co->takesFocus = 1; + co->takesFocus = 0; /* we may have 0 components */ co->ops = &formOps; form->help = help; @@ -140,6 +144,8 @@ void newtFormSetWidth(newtComponent co, int width) { void newtFormAddComponent(newtComponent co, newtComponent newco) { struct form * form = co->data; + co->takesFocus = 1; + if (form->numCompsAlloced == form->numComps) { form->numCompsAlloced += 5; form->elements = realloc(form->elements, @@ -169,6 +175,27 @@ void newtFormAddComponents(newtComponent co, ...) { va_end(ap); } +static void formPlace(newtComponent co, int left, int top) { + struct form * form = co->data; + int vertDelta, horizDelta; + struct element * el; + int i; + + newtFormSetSize(co); + + vertDelta = top - co->top; + horizDelta = left - co->left; + co->top = top; + co->left = left; + + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + el->co->top += vertDelta; + el->top += vertDelta; + el->co->left += horizDelta; + el->left += horizDelta; + } +} + void newtDrawForm(newtComponent co) { struct form * form = co->data; struct element * el; @@ -179,17 +206,18 @@ void newtDrawForm(newtComponent co) { SLsmg_set_color(form->background); newtClearBox(co->left, co->top, co->width, co->height); for (i = 0, el = form->elements; i < form->numComps; i++, el++) { - /* the scrollbar *always* fits */ - if (el->co == form->vertBar) + /* the scrollbar *always* fits somewhere */ + if (el->co == form->vertBar) { + el->co->ops->mapped(el->co, 1); el->co->ops->draw(el->co); - else { + } else { /* only draw it if it'll fit on the screen vertically */ if (componentFits(co, i)) { el->co->top = el->top - form->vertOffset; - el->co->isMapped = 1; + el->co->ops->mapped(el->co, 1); el->co->ops->draw(el->co); } else { - el->co->top = -1; /* tell it not to draw itself */ + el->co->ops->mapped(el->co, 0); } } } @@ -208,6 +236,9 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { int i, num; er.result = ER_IGNORED; + if (!form->numComps) return er; + + subco = form->elements[form->currComp].co; switch (ev.when) { case EV_EARLY: @@ -223,14 +254,16 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { } } - i = form->currComp; - num = 0; - while (er.result == ER_IGNORED && num != form->numComps ) { - er = form->elements[i].co->ops->event(form->elements[i].co, ev); + if (form->numComps) { + i = form->currComp; + num = 0; + while (er.result == ER_IGNORED && num != form->numComps ) { + er = form->elements[i].co->ops->event(form->elements[i].co, ev); - num++; - i++; - if (i == form->numComps) i = 0; + num++; + i++; + if (i == form->numComps) i = 0; + } } break; @@ -394,8 +427,8 @@ void newtFormSetSize(newtComponent co) { form->beenSet = 1; - /* figure out how big we are -- we do this as late as possible (i.e. here) - to let grids delay there decisions as long as possible */ + if (!form->numComps) return; + co->width = 0; if (!form->fixedHeight) co->height = 0; diff --git a/grid.c b/grid.c index cd2d781..e2924b2 100644 --- a/grid.c +++ b/grid.c @@ -22,6 +22,9 @@ struct grid_s { struct gridField ** fields; }; +/* this is a bit of a hack */ +extern struct componentOps formOps[]; + newtGrid newtCreateGrid(int cols, int rows) { newtGrid grid; @@ -101,6 +104,8 @@ static void shuffleGrid(newtGrid grid, int left, int top, int set) { shuffleGrid(field->u.grid, left, top, 0); j = field->u.grid->width; } else if (field->type == NEWT_GRID_COMPONENT) { + if (field->u.co->ops == formOps) + newtFormSetSize(field->u.co); j = field->u.co->width; } else j = 0; @@ -193,10 +198,7 @@ static void shuffleGrid(newtGrid grid, int left, int top, int set) { shuffleGrid(field->u.grid, x, y, 1); } else if (field->type == NEWT_GRID_COMPONENT) { - field->u.co->left = x; - field->u.co->top = y; - if (field->u.co->ops->place) - field->u.co->ops->place(field->u.co); + field->u.co->ops->place(field->u.co, x, y); } thisLeft += widths[col]; @@ -250,7 +252,7 @@ void newtGridWrappedWindowAt(newtGrid grid, char * title, int left, int top) { int width, height; newtGridGetSize(grid, &width, &height); - newtOpenWindow(left, top, left + width, top + height, title); + newtOpenWindow(left, top, width + 2, height + 2, title); newtGridPlace(grid, 1, 1); } @@ -271,7 +273,7 @@ void newtGridAddComponentsToForm(newtGrid grid, newtComponent form, /* this handles up to 50 items */ static newtGrid stackem(int isVert, enum newtGridElement type1, void * what1, - va_list args) { + va_list args, int close) { struct item { enum newtGridElement type; void * what; @@ -293,22 +295,46 @@ static newtGrid stackem(int isVert, enum newtGridElement type1, void * what1, for (i = 0; i < num; i++) { newtGridSetField(grid, isVert ? 0 : i, isVert ? i : 0, items[i].type, items[i].what, - i ? (isVert ? 0 : 1) : 0, - i ? (isVert ? 1 : 0) : 0, 0, 0, 0, - items[i].type == NEWT_GRID_SUBGRID ? - NEWT_GRID_FLAG_GROWX : 0); + close ? 0 : (i ? (isVert ? 0 : 1) : 0), + close ? 0 : (i ? (isVert ? 1 : 0) : 0), 0, 0, 0, 0); } return grid; } +newtGrid newtGridHCloseStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(0, type1, what1, args, 1); + + va_start(args, what1); + + return grid; +} + +newtGrid newtGridVCloseStacked(enum newtGridElement type1, void * what1, ...) { + va_list args; + newtGrid grid; + + va_start(args, what1); + + grid = stackem(1, type1, what1, args, 1); + + va_start(args, what1); + + return grid; +} + newtGrid newtGridVStacked(enum newtGridElement type1, void * what1, ...) { va_list args; newtGrid grid; va_start(args, what1); - grid = stackem(1, type1, what1, args); + grid = stackem(1, type1, what1, args, 0); va_start(args, what1); @@ -321,9 +347,39 @@ newtGrid newtGridHStacked(enum newtGridElement type1, void * what1, ...) { va_start(args, what1); - grid = stackem(0, type1, what1, args); + grid = stackem(0, type1, what1, args, 0); va_start(args, what1); return grid; } + +newtGrid newtGridBasicWindow(newtComponent text, newtGrid middle, + newtGrid buttons) { + newtGrid grid; + + grid = newtCreateGrid(1, 3); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, middle, + 0, 1, 0, 0, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + return grid; +} + +newtGrid newtGridSimpleWindow(newtComponent text, newtComponent middle, + newtGrid buttons) { + newtGrid grid; + + grid = newtCreateGrid(1, 3); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, middle, + 0, 1, 0, 0, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + return grid; +} diff --git a/label.c b/label.c index 5c253cd..f7e1394 100644 --- a/label.c +++ b/label.c @@ -17,7 +17,8 @@ static struct componentOps labelOps = { labelDraw, newtDefaultEventHandler, labelDestroy, - NULL, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, } ; newtComponent newtLabel(int left, int top, const char * text) { diff --git a/listbox.c b/listbox.c index 249db8d..dee5990 100644 --- a/listbox.c +++ b/listbox.c @@ -44,25 +44,35 @@ static void listboxDraw(newtComponent co); static void listboxDestroy(newtComponent co); static struct eventResult listboxEvent(newtComponent co, struct event ev); static void newtListboxRealSetCurrent(newtComponent co); -static void listboxPlace(newtComponent co); +static void listboxPlace(newtComponent co, int newLeft, int newTop); static inline void updateWidth(newtComponent co, struct listbox * li, int maxField); +static void listboxMapped(newtComponent co, int isMapped); static struct componentOps listboxOps = { listboxDraw, listboxEvent, listboxDestroy, listboxPlace, + listboxMapped, }; -static void listboxPlace(newtComponent co) { +static void listboxMapped(newtComponent co, int isMapped) { struct listbox * li = co->data; - if (li->sb) { - li->sb->top = co->top; - li->sb->left = co->left + co->width - 1; - if (li->sb->ops->place) li->sb->ops->place(li->sb); - } + co->isMapped = isMapped; + if (li->sb) + li->sb->ops->mapped(li->sb, isMapped); +} + +static void listboxPlace(newtComponent co, int newLeft, int newTop) { + struct listbox * li = co->data; + + co->top = newTop; + co->left = newLeft; + + if (li->sb) + li->sb->ops->place(li->sb, co->left + co->width - 1, co->top); } newtComponent newtListbox(int left, int top, int height, int flags) { diff --git a/newt.c b/newt.c index 8382d16..c36afb7 100644 --- a/newt.c +++ b/newt.c @@ -618,3 +618,12 @@ void newtGetScreenSize(int * cols, int * rows) { if (rows) *rows = SLtt_Screen_Rows; if (cols) *cols = SLtt_Screen_Cols; } + +void newtDefaultPlaceHandler(newtComponent c, int newLeft, int newTop) { + c->left = newLeft; + c->top = newTop; +} + +void newtDefaultMappedHandler(newtComponent c, int isMapped) { + c->isMapped = isMapped; +} diff --git a/newt.h b/newt.h index 30663ce..12dbb2f 100644 --- a/newt.h +++ b/newt.h @@ -250,7 +250,13 @@ enum newtGridElement { NEWT_GRID_EMPTY = 0, newtGrid newtCreateGrid(int cols, int rows); /* TYPE, what, TYPE, what, ..., NULL */ newtGrid newtGridVStacked(enum newtGridElement type, void * what, ...); +newtGrid newtGridVCloseStacked(enum newtGridElement type, void * what, ...); newtGrid newtGridHStacked(enum newtGridElement type1, void * what1, ...); +newtGrid newtGridHCloseStacked(enum newtGridElement type1, void * what1, ...); +newtGrid newtGridBasicWindow(newtComponent text, newtGrid middle, + newtGrid buttons); +newtGrid newtGridSimpleWindow(newtComponent text, newtComponent middle, + newtGrid buttons); void newtGridSetField(newtGrid grid, int col, int row, enum newtGridElement type, void * val, int padLeft, int padTop, int padRight, int padBottom, int anchor, diff --git a/newt_pr.h b/newt_pr.h index 9f1f034..5a5e21e 100644 --- a/newt_pr.h +++ b/newt_pr.h @@ -65,9 +65,12 @@ struct componentOps { void (* draw)(newtComponent c); struct eventResult (* event)(newtComponent c, struct event ev); void (* destroy)(newtComponent c); - void (* place)(newtComponent c); + void (* place)(newtComponent c, int newLeft, int newTop); + void (* mapped)(newtComponent c, int isMapped); } ; +void newtDefaultPlaceHandler(newtComponent c, int newLeft, int newTop); +void newtDefaultMappedHandler(newtComponent c, int isMapped); struct eventResult newtDefaultEventHandler(newtComponent c, struct event ev); diff --git a/scale.c b/scale.c index e9327db..11c72cc 100644 --- a/scale.c +++ b/scale.c @@ -16,7 +16,8 @@ static struct componentOps scaleOps = { scaleDraw, newtDefaultEventHandler, NULL, - NULL, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, } ; newtComponent newtScale(int left, int top, int width, long long fullValue) { diff --git a/scrollbar.c b/scrollbar.c index 47ac814..5235d7a 100644 --- a/scrollbar.c +++ b/scrollbar.c @@ -18,7 +18,8 @@ static struct componentOps sbOps = { sbDraw, newtDefaultEventHandler, sbDestroy, - NULL, + newtDefaultPlaceHandler, + newtDefaultMappedHandler, } ; void newtScrollbarSet(newtComponent co, int where, int total) { diff --git a/textbox.c b/textbox.c index 00f8ece..0f55b8a 100644 --- a/textbox.c +++ b/textbox.c @@ -13,6 +13,7 @@ struct textbox { int doWrap; newtComponent sb; int topLine; + int textWidth; }; static void addLine(newtComponent co, const char * s, int len); @@ -21,14 +22,35 @@ static void addShortLine(newtComponent co, const char * s, int len); 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, - NULL, + 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; } @@ -69,19 +91,20 @@ newtComponent newtTextbox(int left, int top, int width, int height, int flags) { 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 = width - 2; - tb->sb = newtVerticalScrollbar(co->left + co->width + 1, co->top, + co->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; } @@ -204,18 +227,18 @@ static void addLine(newtComponent co, const char * s, int origlen) { if (origlen < 0) origlen = strlen(s); len = origlen; - if (!tb->doWrap || len <= co->width) { + if (!tb->doWrap || len <= tb->textWidth) { addShortLine(co, s, len); } else { /* word wrap */ start = s; - while (len > co->width) { - end = start + co->width - 1; + while (len > tb->textWidth) { + end = start + tb->textWidth - 1; while (end > start && !isspace(*end)) end--; if (end == start) - end = start + co->width - 1; + end = start + tb->textWidth - 1; addShortLine(co, start, end - start); @@ -238,12 +261,12 @@ static void addShortLine(newtComponent co, const char * s, int len) { tb->lines = realloc(tb->lines, (sizeof(char *) * tb->linesAlloced)); } - if (len > co->width) len = co->width; + if (len > tb->textWidth) len = tb->textWidth; - tb->lines[tb->numLines] = malloc(co->width + 1); + tb->lines[tb->numLines] = malloc(tb->textWidth + 1); strncpy(tb->lines[tb->numLines], s, len); - while (len < co->width) tb->lines[tb->numLines][len++] = ' '; + while (len < tb->textWidth) tb->lines[tb->numLines][len++] = ' '; tb->lines[tb->numLines++][len] = '\0'; } diff --git a/windows.c b/windows.c index 907d665..e0bc9ef 100644 --- a/windows.c +++ b/windows.c @@ -47,9 +47,10 @@ static void * newtvwindow(char * title, char * button1, char * button2, newtGridSetField(buttonGrid, 0, 0, NEWT_GRID_COMPONENT, b1, 0, 0, button2 ? 1 : 0, 0, 0, 0); - grid = newtGridVStacked(NEWT_GRID_COMPONENT, t, - NEWT_GRID_SUBGRID, buttonGrid, - NEWT_GRID_EMPTY); + grid = newtCreateGrid(1, 2); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, t, 0, 0, 0, 0, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttonGrid, + 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); newtGridWrappedWindow(grid, title); f = newtForm(NULL, NULL, 0); @@ -170,11 +171,7 @@ int newtWinMenu(char * title, char * text, int suggestedWidth, int flexDown, i ? 1 : 0, 0, 0, 0, 0, 0); } - grid = newtGridVStacked(NEWT_GRID_COMPONENT, textbox, - NEWT_GRID_COMPONENT, listbox, - NEWT_GRID_SUBGRID, buttonBar, - NEWT_GRID_EMPTY); - + grid = newtGridSimpleWindow(textbox, listbox, buttonBar); newtGridWrappedWindow(grid, title); form = newtForm(NULL, 0, 0); -- 2.39.2