]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
added vertical scrolling ability when all components are of height
authorewt <ewt>
Tue, 26 Mar 1996 04:14:10 +0000 (04:14 +0000)
committerewt <ewt>
Tue, 26 Mar 1996 04:14:10 +0000 (04:14 +0000)
one (though more general vertical scrolling should be trivial to
implement)

form.c

diff --git a/form.c b/form.c
index a158659e44a0ce878f18ecfeafe394083aa56f47..90125439111adee2767b2868ea8e9f4807bbd1f9 100644 (file)
--- 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);
+    }
 }