#include "newt.h"
#include "newt_pr.h"
-struct newtForm {
+struct form {
int numCompsAlloced;
newtComponent * comps;
int numComps;
int currComp;
};
-newtForm newtCreateForm(void) {
- newtForm form;
+static void formDraw(newtComponent co);
+static void gotoComponent(struct form * form, int newComp);
+static struct eventResult formEvent(newtComponent co, struct event ev);
+
+static struct componentOps formOps = {
+ formDraw,
+ formEvent,
+ newtFormDestroy,
+} ;
+
+newtComponent newtForm(void) {
+ newtComponent co;
+ struct form * form;
+
+ co = malloc(sizeof(*co));
+ form = malloc(sizeof(*form));
+ co->data = form;
+ co->width = 0;
+ co->height = 0;
+ co->top = -1;
+ co->left = -1;
+
+ co->takesFocus = 0;
+ co->ops = &formOps;
form = malloc(sizeof(*form));
form->numCompsAlloced = 5;
form->currComp = -1;
form->comps = malloc(sizeof(*(form->comps)) * form->numCompsAlloced);
- return form;
+ return co;
}
-static void gotoComponent(newtForm form, int newComp);
+void newtFormAddComponent(newtComponent co, newtComponent newco) {
+ struct form * form = co->data;
+ int delta;
-void newtAddComponentToForm(newtForm form, newtComponent co) {
if (form->numCompsAlloced == form->numComps) {
form->numCompsAlloced += 5;
form->comps = realloc(form->comps,
sizeof(*(form->comps)) * form->numCompsAlloced);
}
- form->comps[form->numComps++] = co;
+ form->comps[form->numComps++] = newco;
+
+ if (co->left == -1) {
+ co->left = newco->left;
+ co->top = newco->top;
+ 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 (co->top > newco->top) {
+ delta = co->top - newco->top;
+ co->top -= delta;
+ co->height += delta;
+ }
+
+ if ((co->left + co->width) < (newco->left + newco->width))
+ co->left = (newco->left + newco->width) - co->width;
+
+ if ((co->top + co->height) < (newco->top + newco->height))
+ co->top = (newco->top + newco->height) - co->height;
+ }
}
-void newtAddComponentsToForm(newtForm form, ...) {
+void newtFormAddComponents(newtComponent co, ...) {
va_list ap;
- newtComponent co;
+ newtComponent subco;
- va_start(ap, form);
+ va_start(ap, co);
- while ((co = va_arg(ap, newtComponent)))
- newtAddComponentToForm(form, co);
+ while ((subco = va_arg(ap, newtComponent)))
+ newtFormAddComponent(co, subco);
va_end(ap);
}
-newtComponent newtRunForm(newtForm form) {
+static void formDraw(newtComponent co) {
+ struct form * form = co->data;
+ newtComponent subco;
int i;
- newtComponent co;
- struct event ev;
- struct eventResult er;
- int key, new;
- /* first, draw all of the components */
for (i = 0; i < form->numComps; i++) {
- co = form->comps[i];
- co->ops->draw(co);
+ subco = form->comps[i];
+ subco->ops->draw(subco);
}
+}
- if (form->currComp == -1)
- gotoComponent(form, 0);
-
- do {
- co = form->comps[form->currComp];
-
- /*newtGotorc(0, 0);*/
- newtRefresh();
- key = newtGetKey();
+static struct eventResult formEvent(newtComponent co, struct event ev) {
+ struct form * form = co->data;
+ newtComponent subco = form->comps[form->currComp];
+ int new;
+ struct eventResult er;
- er.result = ER_IGNORED;
+ er.result = ER_IGNORED;
- /* handle system wide events */
- switch (key) {
- case NEWT_KEY_TAB:
- new = form->currComp + 1;
- if (new == form->numComps) new = 0;
- gotoComponent(form, new);
- er.result = ER_SWALLOWED;
- break;
- }
+ switch (ev.event) {
+ case EV_FOCUS:
+ case EV_UNFOCUS:
+ er = subco->ops->event(subco, ev);
+ break;
+
+ case EV_KEYPRESS:
+ if (ev.u.key == NEWT_KEY_TAB) {
+ er.result = ER_NEXTCOMP;
+ }
- /* handle component specific events */
if (er.result == ER_IGNORED) {
- ev.event = EV_KEYPRESS;
- ev.u.key = key;
- er = co->ops->event(co, ev);
+ /* let the current component handle the event */
+ er = subco->ops->event(subco, ev);
}
- /* handle default events */
if (er.result == ER_IGNORED) {
- switch (key) {
- case NEWT_KEY_UP:
- case NEWT_KEY_LEFT:
- case NEWT_KEY_BKSPC:
- if (form->currComp == 0)
- new = form->numComps - 1;
- else
- new = form->currComp - 1;
-
- gotoComponent(form, new);
- break;
-
- case NEWT_KEY_DOWN:
- case NEWT_KEY_RIGHT:
- case NEWT_KEY_ENTER:
- new = form->currComp + 1;
- if (new == form->numComps) new = 0;
- gotoComponent(form, new);
- break;
+ /* handle default events */
+ if (er.result == ER_IGNORED) {
+ switch (ev.u.key) {
+ case NEWT_KEY_UP:
+ case NEWT_KEY_LEFT:
+ case NEWT_KEY_BKSPC:
+ er.result = ER_PREVCOMP;
+ break;
+
+ case NEWT_KEY_DOWN:
+ case NEWT_KEY_RIGHT:
+ case NEWT_KEY_ENTER:
+ er.result = ER_NEXTCOMP;
+ break;
+ }
}
}
-
- } while (er.result != ER_EXITFORM);
+ }
- newtRefresh();
+ /* 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;
+ }
+ } else if (er.result == ER_NEXTCOMP) {
+ new = form->currComp + 1;
+ if (new < form->numComps) {
+ gotoComponent(form, new);
+ er.result = ER_SWALLOWED;
+ }
+ }
- return form->comps[form->currComp];
+ return er;
}
/* this also destroys all of the components on the form */
-void newtDestroyForm(newtForm form) {
+void newtFormDestroy(newtComponent co) {
int i;
- newtComponent co;
+ newtComponent subco;
+ struct form * form = co->data;
/* first, destroy all of the components */
for (i = 0; i < form->numComps; i++) {
- co = form->comps[i];
- if (co->ops->destroy) {
- co->ops->destroy(co);
+ subco = form->comps[i];
+ if (subco->ops->destroy) {
+ subco->ops->destroy(subco);
} else {
- if (co->data) free(co->data);
- free(co);
+ if (subco->data) free(subco->data);
+ free(subco);
}
}
free(form->comps);
free(form);
+ free(co);
+}
+
+newtComponent newtRunForm(newtComponent co) {
+ struct form * form = co->data;
+ struct event ev;
+ struct eventResult er;
+ int key;
+
+ /* first, draw all of the components */
+ formDraw(co);
+
+ if (form->currComp == -1)
+ gotoComponent(form, 0);
+ else
+ gotoComponent(form, form->currComp);
+
+ do {
+ newtRefresh();
+ key = newtGetKey();
+
+ ev.event = EV_KEYPRESS;
+ ev.u.key = key;
+ er = formEvent(co, ev);
+
+ /* EV_NEXTCOMP and EV_PREVCOMP should cause wrapping */
+ } while (er.result != ER_EXITFORM);
+
+ newtRefresh();
+
+ return form->comps[form->currComp];
+
}
-static void gotoComponent(newtForm form, int newComp) {
+static void gotoComponent(struct form * form, int newComp) {
newtComponent co;
struct event ev;
/* Components */
typedef struct newtComponent * newtComponent;
-typedef struct newtForm * newtForm;
newtComponent newtButton(int left, int top, char * text);
newtComponent newtCheckbox(int left, int top, char * text, char defValue,
newtComponent newtRadiobutton(int left, int top, char * text, int isDefault,
newtComponent prevButton);
+newtComponent newtForm(void);
+void newtFormAddComponent(newtComponent form, newtComponent co);
+void newtFormAddComponents(newtComponent form, ...);
+newtComponent newtRunForm(newtComponent form);
+
#define NEWT_ENTRY_SCROLL (1 << 0)
#define NEWT_ENTRY_HIDDEN (1 << 1)
newtComponent newtEntry(int left, int top, char * initialValue, int width,
char ** resultPtr, int flags);
-/* Forms */
-
-newtForm newtCreateForm(void);
-void newtAddComponentToForm(newtForm form, newtComponent co);
-void newtAddComponentsToForm(newtForm form, ...);
-newtComponent newtRunForm(newtForm form);
-/* this also destroys all of the components on the form */
-void newtDestroyForm(newtForm form);
+/* this also destroys all of the components (including other forms) on the
+ form */
+void newtFormDestroy(newtComponent form);
/* Key codes */
void main(void) {
newtComponent b1, b2, c1, c2, r1, r2, r3, e1, e2, e3;
- newtForm f;
+ newtComponent f, chklist;
char result, result2;
char * enr1, * enr2, * enr3;
newtOpenWindow(2, 5, 30, 10, "first window");
newtOpenWindow(20, 10, 40, 13, "window 2");
- f = newtCreateForm();
+ f = newtForm();
+ chklist = newtForm();
b1 = newtButton(3, 1, "Push me");
b2 = newtButton(18, 1, "Not me");
e2 = newtEntry(3, 11, "Default", 20, &enr2, NEWT_ENTRY_SCROLL);
e3 = newtEntry(3, 12, NULL, 20, &enr3, NEWT_ENTRY_HIDDEN);
- newtAddComponentsToForm(f, b1, b2, c1, c2, NULL);
- newtAddComponentsToForm(f, r1, r2, r3, e1, e2, e3, NULL);
+ newtFormAddComponents(chklist, c1, c2, NULL);
+
+ newtFormAddComponents(f, b1, b2, chklist, NULL);
+ newtFormAddComponents(f, r1, r2, r3, e1, e2, e3, NULL);
newtRunForm(f);
enr2 = strdup(enr2);
enr3 = strdup(enr3);
- newtDestroyForm(f);
+ newtFormDestroy(f);
newtPopWindow();
newtPopWindow();