From: ewt Date: Tue, 26 Mar 1996 04:14:10 +0000 (+0000) Subject: added vertical scrolling ability when all components are of height X-Git-Tag: 0-1~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5daa14e4344c4db271e64d0bc4d63f1d1eb4f94;p=thirdparty%2Fnewt.git added vertical scrolling ability when all components are of height one (though more general vertical scrolling should be trivial to implement) --- diff --git a/form.c b/form.c index a158659..9012543 100644 --- a/form.c +++ b/form.c @@ -4,11 +4,27 @@ #include "newt.h" #include "newt_pr.h" +/**************************************************************************** + These forms handle vertical scrolling of components with a height of 1 + + Horizontal scrolling won't work, and scrolling large widgets will fail + miserably. It shouldn't be too hard to fix either of those if anyone + cares to. I only use scrolling for listboxes and text boxes though so + I didn't bother. +*****************************************************************************/ + +struct element { + int top, left; /* actual, not virtual */ + newtComponent co; +}; + struct form { int numCompsAlloced; - newtComponent * comps; + struct element * elements; int numComps; int currComp; + int fixedSize; + int vertOffset; }; static void formDraw(newtComponent co); @@ -21,6 +37,17 @@ static struct componentOps formOps = { newtFormDestroy, } ; +static inline int componentFits(newtComponent co, int compNum) { + struct form * form = co->data; + struct element * el = form->elements + compNum; + + if ((co->top + form->vertOffset) > el->top) return 0; + if ((co->top + form->vertOffset + co->height) < + (el->top + el->co->height)) return 0; + + return 1; +} + newtComponent newtForm(void) { newtComponent co; struct form * form; @@ -33,53 +60,72 @@ newtComponent newtForm(void) { co->top = -1; co->left = -1; - co->takesFocus = 0; + co->takesFocus = 1; co->ops = &formOps; form = malloc(sizeof(*form)); form->numCompsAlloced = 5; form->numComps = 0; form->currComp = -1; - form->comps = malloc(sizeof(*(form->comps)) * form->numCompsAlloced); + form->vertOffset = 0; + form->fixedSize = 0; + form->elements = malloc(sizeof(*(form->elements)) * form->numCompsAlloced); return co; } +void newtFormSetSize(newtComponent co, int width, int height) { + struct form * form = co->data; + + form->fixedSize = 1; + co->width = width; + co->height = height; +} + void newtFormAddComponent(newtComponent co, newtComponent newco) { struct form * form = co->data; int delta; if (form->numCompsAlloced == form->numComps) { form->numCompsAlloced += 5; - form->comps = realloc(form->comps, - sizeof(*(form->comps)) * form->numCompsAlloced); + form->elements = realloc(form->elements, + sizeof(*(form->elements)) * form->numCompsAlloced); } - form->comps[form->numComps++] = newco; + form->elements[form->numComps].left = newco->left; + form->elements[form->numComps].top = newco->top; + form->elements[form->numComps].co = newco; + form->numComps++; if (co->left == -1) { co->left = newco->left; co->top = newco->top; - co->width = newco->width; - co->height = newco->height; + if (!form->fixedSize) { + co->width = newco->width; + co->height = newco->height; + } } else { if (co->left > newco->left) { delta = co->left - newco->left; co->left -= delta; - co->width += delta; + if (!form->fixedSize) + co->width += delta; } if (co->top > newco->top) { delta = co->top - newco->top; co->top -= delta; - co->height += delta; + if (!form->fixedSize) + co->height += delta; } - if ((co->left + co->width) < (newco->left + newco->width)) - co->left = (newco->left + newco->width) - co->width; + if (!form->fixedSize) { + if ((co->left + co->width) < (newco->left + newco->width)) + co->width = (newco->left + newco->width) - co->left; - if ((co->top + co->height) < (newco->top + newco->height)) - co->top = (newco->top + newco->height) - co->height; + if ((co->top + co->height) < (newco->top + newco->height)) + co->height = (newco->top + newco->height) - co->top; + } } } @@ -97,20 +143,26 @@ void newtFormAddComponents(newtComponent co, ...) { static void formDraw(newtComponent co) { struct form * form = co->data; - newtComponent subco; + struct element * el; int i; - for (i = 0; i < form->numComps; i++) { - subco = form->comps[i]; - subco->ops->draw(subco); + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + /* only draw it if it'll fit on the screen vertically */ + if (componentFits(co, i)) { + el->co->top = el->top - form->vertOffset; + el->co->ops->draw(el->co); + } else { + el->co->top = -1; /* tell it not to draw itself */ + } } } static struct eventResult formEvent(newtComponent co, struct event ev) { struct form * form = co->data; - newtComponent subco = form->comps[form->currComp]; + newtComponent subco = form->elements[form->currComp].co; int new; struct eventResult er; + int dir = 0; er.result = ER_IGNORED; @@ -152,17 +204,39 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { /* we try and do previous/next actions ourselves if possible */ if (er.result == ER_PREVCOMP) { - if (form->currComp > 0) { - new = form->currComp - 1; - gotoComponent(form, new); - er.result = ER_SWALLOWED; - } + dir = -1; } else if (er.result == ER_NEXTCOMP) { - new = form->currComp + 1; - if (new < form->numComps) { - gotoComponent(form, new); - er.result = ER_SWALLOWED; + dir = 1; + } + + if (dir) { + new = form->currComp; + do { + new += dir; + if (new < 0 || new >= form->numComps) return er; + } while (!form->elements[new].co->takesFocus); + + /* make sure this component is visible */ + if (!componentFits(co, new)) { + gotoComponent(form, -1); + + if (dir < 0) { + /* make the new component the first one */ + form->vertOffset = form->elements[new].top - co->top; + } else { + /* make the new component the last one */ + form->vertOffset = (form->elements[new].top + + form->elements[new].co->height) - + (co->top + co->height); + } + + if (form->vertOffset < 0) form->vertOffset = 0; + + formDraw(co); } + + gotoComponent(form, new); + er.result = ER_SWALLOWED; } return er; @@ -176,7 +250,7 @@ void newtFormDestroy(newtComponent co) { /* first, destroy all of the components */ for (i = 0; i < form->numComps; i++) { - subco = form->comps[i]; + subco = form->elements[i].co; if (subco->ops->destroy) { subco->ops->destroy(subco); } else { @@ -185,7 +259,7 @@ void newtFormDestroy(newtComponent co) { } } - free(form->comps); + free(form->elements); free(form); free(co); } @@ -217,7 +291,7 @@ newtComponent newtRunForm(newtComponent co) { newtRefresh(); - return form->comps[form->currComp]; + return form->elements[form->currComp].co; } @@ -227,13 +301,16 @@ static void gotoComponent(struct form * form, int newComp) { if (form->currComp != -1) { ev.event = EV_UNFOCUS; - co = form->comps[form->currComp]; + co = form->elements[form->currComp].co; co->ops->event(co, ev); } form->currComp = newComp; - ev.event = EV_FOCUS; - co = form->comps[form->currComp]; - co->ops->event(co, ev); + + if (form->currComp != -1) { + ev.event = EV_FOCUS; + co = form->elements[form->currComp].co; + co->ops->event(co, ev); + } }