From 45f6c4fd82d12395fc180c6964ec33033ffba710 Mon Sep 17 00:00:00 2001 From: msw Date: Thu, 7 Jan 1999 05:19:55 +0000 Subject: [PATCH] Mouse support --- .cvsignore | 4 +- CHANGES | 3 + button.c | 17 ++++- checkbox.c | 32 ++++++++-- entry.c | 47 +++++++++----- form.c | 174 ++++++++++++++++++++++++++++++++++++++-------------- listbox.c | 94 +++++++++++++++++++++------- newt.c | 56 ++++++++++------- newt.spec | 1 + newt_pr.h | 15 +++-- scrollbar.c | 31 ++++++++-- test.c | 6 +- textbox.c | 18 +++++- 13 files changed, 370 insertions(+), 128 deletions(-) diff --git a/.cvsignore b/.cvsignore index 729e18e..3724381 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,10 +1,12 @@ configure config.log config.cache +config.status config.h +.depend Makefile test testgrid whiptail libnewt* -snack.pcy +snack.pyc diff --git a/CHANGES b/CHANGES index fcfdc4c..2edad3c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +0.30 -> 0.40 + - GPM mouse support added + 0.30 -> 0.31: - pgdn could core dump on short textboxes diff --git a/button.c b/button.c index f1a3593..ec97787 100644 --- a/button.c +++ b/button.c @@ -92,7 +92,7 @@ static void buttonDrawIt(newtComponent co, int active, int pushed) { SLsmg_set_color(NEWT_COLORSET_BUTTON); if (bu->compact) { - if (active) + if (active) SLsmg_set_color(NEWT_COLORSET_COMPACTBUTTON); else SLsmg_set_color(NEWT_COLORSET_BUTTON); @@ -162,11 +162,22 @@ static struct eventResult buttonEvent(newtComponent co, } er.result = ER_EXITFORM; - } else + } else er.result = ER_IGNORED; break; + case EV_MOUSE: + if (!bu->compact) { + buttonDrawIt(co, 1, 1); + newtRefresh(); + newtDelay(150000); + buttonDrawIt(co, 1, 0); + newtRefresh(); + newtDelay(150000); + } + er.result = ER_EXITFORM; + break; } - } else + } else er.result = ER_IGNORED; return er; diff --git a/checkbox.c b/checkbox.c index 80aeb90..785c17f 100644 --- a/checkbox.c +++ b/checkbox.c @@ -62,7 +62,7 @@ newtComponent newtRadiobutton(int left, int top, const char * text, int isDefaul newtComponent newtRadioGetCurrent(newtComponent setMember) { struct checkbox * rb = setMember->data; - + setMember = rb->lastButton; rb = setMember->data; @@ -147,7 +147,7 @@ static void cbDraw(newtComponent c) { SLsmg_write_string(cb->text); - if (cb->hasFocus) + if (cb->hasFocus) SLsmg_set_color(cb->active); newtGotorc(c->top, c->left + 1); @@ -192,7 +192,7 @@ struct eventResult cbEvent(newtComponent co, struct event ev) { *cb->result = *cb->seq; else { cur++; - if (! *cur) + if (! *cur) *cb->result = *cb->seq; else *cb->result = *cur; @@ -211,8 +211,30 @@ struct eventResult cbEvent(newtComponent co, struct event ev) { er.result = ER_IGNORED; } break; + case EV_MOUSE: + if (ev.u.mouse.type == MOUSE_BUTTON_DOWN) { + if (cb->type == RADIO) { + makeActive(co); + } else if (cb->type == CHECK) { + cur = strchr(cb->seq, *cb->result); + if (!cur) + *cb->result = *cb->seq; + else { + cur++; + if (! *cur) + *cb->result = *cb->seq; + else + *cb->result = *cur; + } + cbDraw(co); + er.result = ER_SWALLOWED; + + if (co->callback) + co->callback(co, co->callbackData); + } + } } - } else + } else er.result = ER_IGNORED; return er; @@ -233,7 +255,7 @@ static void makeActive(newtComponent co) { if (curr) { rb->value = rb->seq[0]; cbDraw(curr); - } + } cb->value = cb->seq[1]; cbDraw(co); diff --git a/entry.c b/entry.c index e5dabd5..a44c63f 100644 --- a/entry.c +++ b/entry.c @@ -20,7 +20,7 @@ struct entry { static void entryDraw(newtComponent co); static void entryDestroy(newtComponent co); -static struct eventResult entryEvent(newtComponent co, +static struct eventResult entryEvent(newtComponent co, struct event ev); static struct eventResult entryHandleKey(newtComponent co, int key); @@ -90,7 +90,7 @@ newtComponent newtEntry(int left, int top, const char * initialValue, int width, en->buf = malloc(en->bufAlloced); en->resultPtr = resultPtr; if (en->resultPtr) *en->resultPtr = en->buf; - + memset(en->buf, 0, en->bufAlloced); if (initialValue) { strcpy(en->buf, initialValue); @@ -113,11 +113,11 @@ static void entryDraw(newtComponent co) { if (!co->isMapped) return; - if (en->flags & NEWT_FLAG_DISABLED) + if (en->flags & NEWT_FLAG_DISABLED) SLsmg_set_color(NEWT_COLORSET_DISENTRY); else SLsmg_set_color(NEWT_COLORSET_ENTRY); - + if (en->flags & NEWT_FLAG_HIDDEN) { newtGotorc(co->top, co->left); for (i = 0; i < co->width; i++) @@ -139,7 +139,7 @@ static void entryDraw(newtComponent co) { chptr = en->buf + en->firstChar; len = strlen(chptr); - + if (len <= co->width) { i = len; SLsmg_write_string(chptr); @@ -181,7 +181,7 @@ static void entryDestroy(newtComponent co) { free(co); } -static struct eventResult entryEvent(newtComponent co, +static struct eventResult entryEvent(newtComponent co, struct event ev) { struct entry * en = co->data; struct eventResult er; @@ -189,29 +189,44 @@ static struct eventResult entryEvent(newtComponent co, if (ev.when == EV_NORMAL) { switch (ev.event) { - case EV_FOCUS: + case EV_FOCUS: /*SLtt_set_cursor_visibility(0);*/ if (en->flags & NEWT_FLAG_HIDDEN) newtGotorc(co->top, co->left); else - newtGotorc(co->top, co->left + - (en->cursorPosition - en->firstChar)); + newtGotorc(co->top, co->left + + (en->cursorPosition - en->firstChar)); er.result = ER_SWALLOWED; break; - case EV_UNFOCUS: + case EV_UNFOCUS: /*SLtt_set_cursor_visibility(1);*/ newtGotorc(0, 0); er.result = ER_SWALLOWED; if (co->callback) co->callback(co, co->callbackData); break; - case EV_KEYPRESS: + case EV_KEYPRESS: ch = ev.u.key; if (en->filter) ch = en->filter(co, en->filterData, ch, en->cursorPosition); if (ch) er = entryHandleKey(co, ch); break; + + case EV_MOUSE: + if ((ev.u.mouse.type == MOUSE_BUTTON_DOWN) && + (en->flags ^ NEWT_FLAG_HIDDEN)) { + if (strlen(en->buf) >= ev.u.mouse.x - co->left) { + en->cursorPosition = ev.u.mouse.x - co->left; + newtGotorc(co->top, + co->left +(en->cursorPosition - en->firstChar)); + } else { + en->cursorPosition = strlen(en->buf); + newtGotorc(co->top, + co->left +(en->cursorPosition - en->firstChar)); + } + } + break; } } else er.result = ER_IGNORED; @@ -294,8 +309,8 @@ static struct eventResult entryHandleKey(newtComponent co, int key) { if (!(en->flags & NEWT_FLAG_SCROLL) && en->bufUsed == co->width) { SLtt_beep(); break; - } - + } + if ((en->bufUsed + 1) == en->bufAlloced) { en->bufAlloced += 20; en->buf = realloc(en->buf, en->bufAlloced); @@ -313,7 +328,7 @@ static struct eventResult entryHandleKey(newtComponent co, int key) { if ((en->bufUsed + 1) == en->bufAlloced) { /* this string fills the buffer, so clip it */ chptr--; - } else + } else en->bufUsed++; insPoint = en->buf + en->cursorPosition; @@ -324,12 +339,12 @@ static struct eventResult entryHandleKey(newtComponent co, int key) { } } - + en->buf[en->cursorPosition++] = key; } else { er.result = ER_IGNORED; } - } + } entryDraw(co); diff --git a/form.c b/form.c index c9b1aa0..66cc631 100644 --- a/form.c +++ b/form.c @@ -1,14 +1,20 @@ +#include "config.h" + #include #include #include #include +#ifdef HAVE_LIBGPM +#include +#endif + #include "newt.h" #include "newt_pr.h" /**************************************************************************** - These forms handle vertical scrolling of components with a height of 1 - + 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 @@ -110,7 +116,7 @@ newtComponent newtForm(newtComponent vertBar, const char * help, int flags) { if (vertBar) form->vertBar = vertBar; else - form->vertBar = NULL; + form->vertBar = NULL; return co; } @@ -160,7 +166,7 @@ void newtFormAddComponent(newtComponent co, newtComponent newco) { if (form->numCompsAlloced == form->numComps) { form->numCompsAlloced += 5; - form->elements = realloc(form->elements, + form->elements = realloc(form->elements, sizeof(*(form->elements)) * form->numCompsAlloced); } @@ -183,7 +189,7 @@ void newtFormAddComponents(newtComponent co, ...) { while ((subco = va_arg(ap, newtComponent))) newtFormAddComponent(co, subco); - + va_end(ap); } @@ -235,7 +241,7 @@ void newtDrawForm(newtComponent co) { } if (form->vertBar) - newtScrollbarSet(form->vertBar, form->vertOffset, + newtScrollbarSet(form->vertBar, form->vertOffset, form->numRows - co->height); } @@ -245,7 +251,8 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { int new, wrap = 0; struct eventResult er; int dir = 0, page = 0; - int i, num; + int i, num, found; + struct element * el; er.result = ER_IGNORED; if (!form->numComps) return er; @@ -254,7 +261,7 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { switch (ev.when) { case EV_EARLY: - if (ev.event == EV_KEYPRESS) { + if (ev.event == EV_KEYPRESS) { if (ev.u.key == NEWT_KEY_TAB) { er.result = ER_SWALLOWED; dir = 1; @@ -279,8 +286,30 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { } break; - + case EV_NORMAL: + if (ev.event == EV_MOUSE) { + found = 0; + for (i = 0, el = form->elements; i < form->numComps; i++, el++) { + if ((el->co->top <= ev.u.mouse.y) && + (el->co->top + el->co->height > ev.u.mouse.y) && + (el->co->left <= ev.u.mouse.x) && + (el->co->left + el->co->width > ev.u.mouse.x)) { + found = 1; + if (el->co->takesFocus) { + gotoComponent(form, i); + subco = form->elements[form->currComp].co; + } + } + /* If we did not find a co to send this event to, we + should just swallow the event here. */ + } + if (!found) { + er.result = ER_SWALLOWED; + + return er; + } + } er = subco->ops->event(subco, ev); switch (er.result) { case ER_NEXTCOMP: @@ -299,7 +328,7 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { case EV_LATE: er = subco->ops->event(subco, ev); - + if (er.result == ER_IGNORED) { switch (ev.u.key) { case NEWT_KEY_UP: @@ -320,7 +349,7 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { dir = -1; page = 1; break; - + case NEWT_KEY_PGDN: er.result = ER_SWALLOWED; dir = 1; @@ -351,7 +380,7 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { new = form->numComps - 1; else if (new >= form->numComps) new = 0; - } else if (new < 0 || new >= form->numComps) + } else if (new < 0 || new >= form->numComps) return er; } while (!form->elements[new].co->takesFocus); } @@ -365,7 +394,7 @@ static struct eventResult formEvent(newtComponent co, struct event ev) { form->vertOffset = form->elements[new].top - co->top; } else { /* make the new component the last one */ - form->vertOffset = (form->elements[new].top + + form->vertOffset = (form->elements[new].top + form->elements[new].co->height) - (co->top + co->height); } @@ -398,7 +427,7 @@ void newtFormDestroy(newtComponent co) { } else { if (subco->data) free(subco->data); free(subco); - } + } } free(form->elements); @@ -466,11 +495,11 @@ void newtFormSetSize(newtComponent co) { co->height += delta; } - if ((co->left + co->width) < (el->co->left + el->co->width)) + if ((co->left + co->width) < (el->co->left + el->co->width)) co->width = (el->co->left + el->co->width) - co->left; if (!form->fixedHeight) { - if ((co->top + co->height) < (el->co->top + el->co->height)) + if ((co->top + co->height) < (el->co->top + el->co->height)) co->height = (el->co->top + el->co->height) - co->top; } @@ -480,13 +509,27 @@ void newtFormSetSize(newtComponent co) { } } + void newtFormRun(newtComponent co, struct newtExitStruct * es) { struct form * form = co->data; struct event ev; struct eventResult er; - int key, i; + int key, i, max; int done = 0; fd_set readSet, writeSet; +#ifdef HAVE_LIBGPM + int x, y; + Gpm_Connect conn; + Gpm_Event event; + + /* Set up GPM interface */ + conn.eventMask = ~GPM_MOVE; + conn.defaultMask = GPM_MOVE; + conn.minMod = 0; + conn.maxMod = 0; + + Gpm_Open(&conn, 0); +#endif newtFormSetSize(co); /* draw all of the components */ @@ -496,13 +539,24 @@ void newtFormRun(newtComponent co, struct newtExitStruct * es) { gotoComponent(form, 0); } else gotoComponent(form, form->currComp); - + while (!done) { newtRefresh(); FD_ZERO(&readSet); FD_ZERO(&writeSet); FD_SET(0, &readSet); +#ifdef HAVE_LIBGPM + if (gpm_visiblepointer) GPM_DRAWPOINTER(&event); + + if (gpm_fd > 0) { + FD_SET(gpm_fd, &readSet); + } + max = form->maxFd > gpm_fd ? form->maxFd : gpm_fd; +#else + max = form->maxFd; +#endif + for (i = 0; i < form->numFds; i++) { if (form->fds[i].flags & NEWT_FD_READ) FD_SET(form->fds[i].fd, &readSet); @@ -510,45 +564,75 @@ void newtFormRun(newtComponent co, struct newtExitStruct * es) { FD_SET(form->fds[i].fd, &writeSet); } - i = select(form->maxFd + 1, &readSet, &writeSet, NULL, NULL); + i = select(max + 1, &readSet, &writeSet, NULL, NULL); if (i < 0) continue; /* ?? What should we do here? */ - if (FD_ISSET(0, &readSet)) { - key = newtGetKey(); +#ifdef HAVE_LIBGPM + if (gpm_fd > 0 && FD_ISSET(gpm_fd, &readSet)) { + Gpm_GetEvent(&event); - if (key == NEWT_KEY_RESIZE) { - /* newtResizeScreen(1); */ - continue; - } + if (event.type & GPM_DOWN) { + /* Transform coordinates to current window */ + newtGetWindowPos(&x, &y); - for (i = 0; i < form->numHotKeys; i++) { - if (form->hotKeys[i] == key) { - es->reason = NEWT_EXIT_HOTKEY; - es->u.key = key; - done = 1; - break; - } - } - - if (!done) { - ev.event = EV_KEYPRESS; - ev.u.key = key; + ev.event = EV_MOUSE; + ev.u.mouse.type = MOUSE_BUTTON_DOWN; + ev.u.mouse.x = event.x - x - 1; + ev.u.mouse.y = event.y - y - 1; + /* Send the form the event */ er = sendEvent(co, ev); - + if (er.result == ER_EXITFORM) { done = 1; es->reason = NEWT_EXIT_COMPONENT; es->u.co = form->exitComp; - } + } + } - } else { - es->reason = NEWT_EXIT_FDREADY; - done = 1; - } - } + } else +#endif + { + if (FD_ISSET(0, &readSet)) { + + key = newtGetKey(); + if (key == NEWT_KEY_RESIZE) { + /* newtResizeScreen(1); */ + continue; + } + + for (i = 0; i < form->numHotKeys; i++) { + if (form->hotKeys[i] == key) { + es->reason = NEWT_EXIT_HOTKEY; + es->u.key = key; + done = 1; + break; + } + } + + if (!done) { + ev.event = EV_KEYPRESS; + ev.u.key = key; + + er = sendEvent(co, ev); + + if (er.result == ER_EXITFORM) { + done = 1; + es->reason = NEWT_EXIT_COMPONENT; + es->u.co = form->exitComp; + } + } + } else { + es->reason = NEWT_EXIT_FDREADY; + done = 1; + } + } + } newtRefresh(); +#ifdef HAVE_LIBGPM + Gpm_Close(); +#endif } static struct eventResult sendEvent(newtComponent co, struct event ev) { @@ -579,7 +663,7 @@ static void gotoComponent(struct form * form, int newComp) { } form->currComp = newComp; - + if (form->currComp != -1) { ev.event = EV_FOCUS; ev.when = EV_NORMAL; diff --git a/listbox.c b/listbox.c index 051c7a6..4363cfb 100644 --- a/listbox.c +++ b/listbox.c @@ -27,7 +27,7 @@ struct listbox { int curHeight; /* size of text w/o border */ int sbAdjust; int bdxAdjust, bdyAdjust; - int numItems, numSelected; + int numItems, numSelected; int userHasSetWidth; int currItem, startShowItem; /* startShowItem is the first item displayed on the screen */ @@ -45,7 +45,7 @@ static void listboxDestroy(newtComponent co); static struct eventResult listboxEvent(newtComponent co, struct event ev); static void newtListboxRealSetCurrent(newtComponent co); static void listboxPlace(newtComponent co, int newLeft, int newTop); -static inline void updateWidth(newtComponent co, struct listbox * li, +static inline void updateWidth(newtComponent co, struct listbox * li, int maxField); static void listboxMapped(newtComponent co, int isMapped); @@ -72,7 +72,7 @@ static void listboxPlace(newtComponent co, int newLeft, int newTop) { co->left = newLeft; if (li->sb) - li->sb->ops->place(li->sb, co->left + co->width - li->bdxAdjust - 1, + li->sb->ops->place(li->sb, co->left + co->width - li->bdxAdjust - 1, co->top); } @@ -98,7 +98,7 @@ newtComponent newtListbox(int left, int top, int height, int flags) { li->sbAdjust = 0; li->bdxAdjust = 0; li->bdyAdjust = 0; - li->flags = flags & (NEWT_FLAG_RETURNEXIT | NEWT_FLAG_BORDER | + li->flags = flags & (NEWT_FLAG_RETURNEXIT | NEWT_FLAG_BORDER | NEWT_FLAG_MULTIPLE); if (li->flags & NEWT_FLAG_BORDER) { @@ -112,8 +112,8 @@ newtComponent newtListbox(int left, int top, int height, int flags) { if (height) { li->grow = 0; if (flags & NEWT_FLAG_SCROLL) { - sb = newtVerticalScrollbar(left, top + li->bdyAdjust, - li->curHeight, + sb = newtVerticalScrollbar(left, top + li->bdyAdjust, + li->curHeight, COLORSET_LISTBOX, COLORSET_ACTLISTBOX); li->sbAdjust = 3; } else { @@ -138,7 +138,7 @@ newtComponent newtListbox(int left, int top, int height, int flags) { return co; } -static inline void updateWidth(newtComponent co, struct listbox * li, +static inline void updateWidth(newtComponent co, struct listbox * li, int maxField) { li->curWidth = maxField; co->width = li->curWidth + li->sbAdjust + 2 * li->bdxAdjust; @@ -195,7 +195,7 @@ static void newtListboxRealSetCurrent(newtComponent co) void newtListboxSetWidth(newtComponent co, int width) { struct listbox * li = co->data; - + co->width = width; li->curWidth = co->width - li->sbAdjust - 2 * li->bdxAdjust; li->userHasSetWidth = 1; @@ -223,7 +223,7 @@ void newtListboxSelectItem(newtComponent co, const void * key, struct listbox * li = co->data; int i; struct items * item; - + item = li->boxItems, i = 0; while (item && item->data != key) item = item->next, i++; @@ -333,7 +333,7 @@ int newtListboxAppendEntry(newtComponent co, const char * text, item->text = strdup(text); item->data = data; item->next = NULL; item->isSelected = 0; - + if (li->grow) co->height++, li->curHeight++; li->numItems++; @@ -373,7 +373,7 @@ int newtListboxInsertEntry(newtComponent co, const char * text, item->text = strdup(text?text:"(null)"); item->data = data; item->isSelected = 0; - + if (li->sb) li->sb->left = co->left + co->width - li->bdxAdjust - 1; li->numItems++; @@ -444,7 +444,7 @@ void newtListboxClear(newtComponent co) } li->numItems = li->numSelected = li->currItem = li->startShowItem = 0; li->boxItems = NULL; - if (!li->userHasSetWidth) + if (!li->userHasSetWidth) updateWidth(co, li, 5); } @@ -464,7 +464,7 @@ void newtListboxGetEntry(newtComponent co, int num, char **text, void **data) { } i = 0; - item = li->boxItems; + item = li->boxItems; while (item && i < num) { i++, item = item->next; } @@ -473,7 +473,7 @@ void newtListboxGetEntry(newtComponent co, int num, char **text, void **data) { if (text) *text = item->text; if (data) - *data = (void *)item->data; + *data = (void *)item->data; } } @@ -498,7 +498,7 @@ static void listboxDraw(newtComponent co) li->sb->ops->draw(li->sb); SLsmg_set_color(NEWT_COLORSET_LISTBOX); - + for(i = 0, item = li->boxItems; item != NULL && i < li->startShowItem; i++, item = item->next); @@ -517,7 +517,7 @@ static void listboxDraw(newtComponent co) SLsmg_set_color(NEWT_COLORSET_SELLISTBOX); else SLsmg_set_color(NEWT_COLORSET_LISTBOX); - + SLsmg_write_nstring(item->text, li->curWidth); } @@ -529,11 +529,11 @@ static struct eventResult listboxEvent(newtComponent co, struct event ev) { struct listbox * li = co->data; er.result = ER_IGNORED; - + if(ev.when == EV_EARLY || ev.when == EV_LATE) { return er; } - + switch(ev.event) { case EV_KEYPRESS: if (!li->isActive) break; @@ -541,7 +541,7 @@ static struct eventResult listboxEvent(newtComponent co, struct event ev) { switch(ev.u.key) { case ' ': if(!(li->flags & NEWT_FLAG_MULTIPLE)) break; - newtListboxSelectItem(co, li->boxItems[li->currItem].data, + newtListboxSelectItem(co, li->boxItems[li->currItem].data, NEWT_FLAGS_TOGGLE); er.result = ER_SWALLOWED; /* We don't break here, because it is cool to be able to @@ -629,7 +629,7 @@ static struct eventResult listboxEvent(newtComponent co, struct event ev) { /* keeps gcc quiet */ } break; - + case EV_FOCUS: li->isActive = 1; listboxDraw(co); @@ -641,6 +641,59 @@ static struct eventResult listboxEvent(newtComponent co, struct event ev) { listboxDraw(co); er.result = ER_SWALLOWED; break; + + case EV_MOUSE: + /* if this mouse click was within the listbox, make the current + item the item clicked on. */ + /* Up scroll arrow */ + if (li->sb && + ev.u.mouse.x == co->left + co->width - li->bdxAdjust - 1 && + ev.u.mouse.y == co->top + li->bdyAdjust) { + if(li->numItems <= 0) break; + if(li->currItem > 0) { + li->currItem--; + if(li->currItem < li->startShowItem) + li->startShowItem = li->currItem; + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + listboxDraw(co); + } + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + } + /* Down scroll arrow */ + if (li->sb && + ev.u.mouse.x == co->left + co->width - li->bdxAdjust - 1 && + ev.u.mouse.y == co->top + co->height - li->bdyAdjust - 1) { + if(li->numItems <= 0) break; + if(li->currItem < li->numItems - 1) { + li->currItem++; + if(li->currItem > (li->startShowItem + li->curHeight - 1)) { + li->startShowItem = li->currItem - li->curHeight + 1; + if(li->startShowItem + li->curHeight > li->numItems) + li->startShowItem = li->numItems - li->curHeight; + } + if(li->sb) + newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); + listboxDraw(co); + } + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + } + if ((ev.u.mouse.y >= co->top + li->bdyAdjust) && + (ev.u.mouse.y <= co->top + co->height - (li->bdyAdjust * 2)) && + (ev.u.mouse.x >= co->left + li->bdxAdjust) && + (ev.u.mouse.x <= co->left + co->width + (li->bdxAdjust * 2))) { + li->currItem = li->startShowItem + + (ev.u.mouse.y - li->bdyAdjust - co->top); + newtListboxRealSetCurrent(co); + listboxDraw(co); + if(co->callback) co->callback(co, co->callbackData); + er.result = ER_SWALLOWED; + break; + } } return er; @@ -662,4 +715,3 @@ static void listboxDestroy(newtComponent co) { free(li); free(co); } - diff --git a/newt.c b/newt.c index 2e2085d..7f1fd56 100644 --- a/newt.c +++ b/newt.c @@ -32,12 +32,12 @@ static char ** currentHelpline = NULL; static int cursorRow, cursorCol; static int needResize; -static const char * defaultHelpLine = +static const char * defaultHelpLine = " / between elements | selects | next screen" ; const struct newtColors newtDefaultColorPalette = { - "white", "blue", /* root fg, bg */ + "white", "blue", /* root fg, bg */ "black", "lightgray", /* border fg, bg */ "black", "lightgray", /* window fg, bg */ "white", "black", /* shadow fg, bg */ @@ -192,7 +192,7 @@ int newtInit(void) { SLsmg_init_smg(); SLang_init_tty(0, 0, 0); - + newtSetColors(newtDefaultColorPalette); /*initKeymap();*/ @@ -205,6 +205,8 @@ int newtInit(void) { SLsignal_intr(SIGWINCH, handleSigwinch); SLang_getkey_intr_hook = getkeyInterruptHook; + + return 0; } @@ -224,25 +226,25 @@ void newtSetColors(struct newtColors colors) { SLtt_set_color(NEWT_COLORSET_SHADOW, "", colors.shadowFg, colors.shadowBg); SLtt_set_color(NEWT_COLORSET_TITLE, "", colors.titleFg, colors.titleBg); SLtt_set_color(NEWT_COLORSET_BUTTON, "", colors.buttonFg, colors.buttonBg); - SLtt_set_color(NEWT_COLORSET_ACTBUTTON, "", colors.actButtonFg, + SLtt_set_color(NEWT_COLORSET_ACTBUTTON, "", colors.actButtonFg, colors.actButtonBg); - SLtt_set_color(NEWT_COLORSET_CHECKBOX, "", colors.checkboxFg, + SLtt_set_color(NEWT_COLORSET_CHECKBOX, "", colors.checkboxFg, colors.checkboxBg); - SLtt_set_color(NEWT_COLORSET_ACTCHECKBOX, "", colors.actCheckboxFg, + SLtt_set_color(NEWT_COLORSET_ACTCHECKBOX, "", colors.actCheckboxFg, colors.actCheckboxBg); SLtt_set_color(NEWT_COLORSET_ENTRY, "", colors.entryFg, colors.entryBg); SLtt_set_color(NEWT_COLORSET_LABEL, "", colors.labelFg, colors.labelBg); - SLtt_set_color(NEWT_COLORSET_LISTBOX, "", colors.listboxFg, + SLtt_set_color(NEWT_COLORSET_LISTBOX, "", colors.listboxFg, colors.listboxBg); - SLtt_set_color(NEWT_COLORSET_ACTLISTBOX, "", colors.actListboxFg, + SLtt_set_color(NEWT_COLORSET_ACTLISTBOX, "", colors.actListboxFg, colors.actListboxBg); - SLtt_set_color(NEWT_COLORSET_TEXTBOX, "", colors.textboxFg, + SLtt_set_color(NEWT_COLORSET_TEXTBOX, "", colors.textboxFg, colors.textboxBg); - SLtt_set_color(NEWT_COLORSET_ACTTEXTBOX, "", colors.actTextboxFg, + SLtt_set_color(NEWT_COLORSET_ACTTEXTBOX, "", colors.actTextboxFg, colors.actTextboxBg); - SLtt_set_color(NEWT_COLORSET_HELPLINE, "", colors.helpLineFg, + SLtt_set_color(NEWT_COLORSET_HELPLINE, "", colors.helpLineFg, colors.helpLineBg); - SLtt_set_color(NEWT_COLORSET_ROOTTEXT, "", colors.rootTextFg, + SLtt_set_color(NEWT_COLORSET_ROOTTEXT, "", colors.rootTextFg, colors.rootTextBg); SLtt_set_color(NEWT_COLORSET_EMPTYSCALE, "", "black", @@ -254,7 +256,7 @@ void newtSetColors(struct newtColors colors) { SLtt_set_color(NEWT_COLORSET_COMPACTBUTTON, "", colors.compactButtonFg, colors.compactButtonBg); - + SLtt_set_color(NEWT_COLORSET_ACTSELLISTBOX, "", colors.actSelListboxFg, colors.actSelListboxBg); SLtt_set_color(NEWT_COLORSET_SELLISTBOX, "", colors.selListboxFg, @@ -336,7 +338,7 @@ int newtGetKey(void) { for later */ chptr--; - while (chptr > buf) + while (chptr > buf) SLang_ungetkey(*chptr--); return *chptr; @@ -355,7 +357,7 @@ void newtClearKeyBuffer(void) { } } -int newtOpenWindow(int left, int top, int width, int height, +int newtOpenWindow(int left, int top, int width, int height, const char * title) { int j, row, col; int n; @@ -427,7 +429,7 @@ int newtCenteredWindow(int width, int height, const char * title) { top = (SLtt_Screen_Rows - height) / 2; - /* I don't know why, but this seems to look better */ + /* I don't know why, but this seems to look better */ if ((SLtt_Screen_Rows % 2) && (top % 2)) top--; left = (SLtt_Screen_Cols - width) / 2; @@ -439,7 +441,7 @@ int newtCenteredWindow(int width, int height, const char * title) { void newtPopWindow(void) { int j, row, col; - int n = 0; + int n = 0; row = col = 0; @@ -455,7 +457,7 @@ void newtPopWindow(void) { free(currentWindow->buffer); free(currentWindow->title); - if (currentWindow == windowStack) + if (currentWindow == windowStack) currentWindow = NULL; else currentWindow--; @@ -465,6 +467,14 @@ void newtPopWindow(void) { newtRefresh(); } +void newtGetWindowPos(int * x, int * y) { + if (currentWindow) { + *x = currentWindow->left; + *y = currentWindow->top; + } else + *x = *y = 0; +} + void newtGetrc(int * row, int * col) { *row = cursorRow; *col = cursorCol; @@ -505,7 +515,7 @@ void newtClearBox(int left, int top, int width, int height) { SLsmg_fill_region(top, left, height, width, ' '); } -#if 0 +#if 0 /* This doesn't seem to work quite right. I don't know why not, but when I rsh from an rxvt into a box and run this code, the machine returns console key's (\033[B) rather then xterm ones (\033OB). */ @@ -550,7 +560,7 @@ void newtRedrawHelpLine(void) { char * buf; SLsmg_set_color(NEWT_COLORSET_HELPLINE); - + buf = alloca(SLtt_Screen_Cols + 1); memset(buf, ' ', SLtt_Screen_Cols); buf[SLtt_Screen_Cols] = '\0'; @@ -565,7 +575,7 @@ void newtRedrawHelpLine(void) { void newtPushHelpLine(const char * text) { if (!text) text = defaultHelpLine; - + if (currentHelpline) (*(++currentHelpline)) = strdup(text); else { @@ -598,7 +608,7 @@ void newtDrawRootText(int col, int row, const char * text) { if (row < 0) { row = SLtt_Screen_Rows + row; } - + SLsmg_gotorc(row, col); SLsmg_write_string((char *)text); } @@ -609,7 +619,7 @@ int newtSetFlags(int oldFlags, int newFlags, enum newtFlagsSense sense) { return oldFlags | newFlags; case NEWT_FLAGS_RESET: - return oldFlags & (~newFlags); + return oldFlags & (~newFlags); case NEWT_FLAGS_TOGGLE: return oldFlags ^ newFlags; diff --git a/newt.spec b/newt.spec index a488067..728bbda 100644 --- a/newt.spec +++ b/newt.spec @@ -33,6 +33,7 @@ widgets and stackable windows. %setup %build +./configure make make shared diff --git a/newt_pr.h b/newt_pr.h index 5a5e21e..76f5e2f 100644 --- a/newt_pr.h +++ b/newt_pr.h @@ -1,8 +1,8 @@ #ifndef H_NEWT_PR #define H_NEWT_PR -#define COLORSET_ROOT NEWT_COLORSET_ROOT -#define COLORSET_BORDER NEWT_COLORSET_BORDER +#define COLORSET_ROOT NEWT_COLORSET_ROOT +#define COLORSET_BORDER NEWT_COLORSET_BORDER #define COLORSET_WINDOW NEWT_COLORSET_WINDOW #define COLORSET_SHADOW NEWT_COLORSET_SHADOW #define COLORSET_TITLE NEWT_COLORSET_TITLE @@ -21,6 +21,7 @@ int newtSetFlags(int oldFlags, int newFlags, enum newtFlagsSense sense); void newtGotorc(int row, int col); void newtGetrc(int * row, int * col); +void newtGetWindowPos(int * x, int * y); void newtDrawBox(int left, int top, int width, int height, int shadow); void newtClearBox(int left, int top, int width, int height); @@ -28,7 +29,7 @@ int newtGetKey(void); struct newtComponent_struct { /* common data */ - int height, width; + int height, width; int top, left; int takesFocus; int isMapped; @@ -48,9 +49,9 @@ struct eventResult { union { newtComponent focus; } u; -}; +}; -enum eventTypes { EV_FOCUS, EV_UNFOCUS, EV_KEYPRESS }; +enum eventTypes { EV_FOCUS, EV_UNFOCUS, EV_KEYPRESS, EV_MOUSE }; enum eventSequence { EV_EARLY, EV_NORMAL, EV_LATE }; struct event { @@ -58,6 +59,10 @@ struct event { enum eventSequence when; union { int key; + struct { + enum { MOUSE_MOTION, MOUSE_BUTTON_DOWN, MOUSE_BUTTON_UP } type; + int x, y; + } mouse; } u; } ; diff --git a/scrollbar.c b/scrollbar.c index 5235d7a..cb4bc27 100644 --- a/scrollbar.c +++ b/scrollbar.c @@ -8,6 +8,7 @@ struct scrollbar { int curr; int cs, csThumb; + int arrows; } ; static void sbDraw(newtComponent co); @@ -26,7 +27,10 @@ void newtScrollbarSet(newtComponent co, int where, int total) { struct scrollbar * sb = co->data; int new; - new = (where * (co->height - 1)) / (total ? total : 1); + if (sb->arrows) + new = (where * (co->height - 3)) / (total ? total : 1) + 1; + else + new = (where * (co->height - 1)) / (total ? total : 1); if (new != sb->curr) { sbDrawThumb(co, 0); sb->curr = new; @@ -43,7 +47,13 @@ newtComponent newtVerticalScrollbar(int left, int top, int height, sb = malloc(sizeof(*sb)); co->data = sb; - sb->curr = 0; + if (!strcmp(getenv("TERM"), "linux") && height >= 2) { + sb->arrows = 1; + sb->curr = 1; + } else { + sb->arrows = 0; + sb->curr = 0; + } sb->cs = normalColorset; sb->csThumb = thumbColorset; @@ -67,9 +77,20 @@ static void sbDraw(newtComponent co) { SLsmg_set_color(sb->cs); SLsmg_set_char_set(1); - for (i = 0; i < co->height; i++) { - newtGotorc(i + co->top, co->left); - SLsmg_write_char('\x61'); + if (sb->arrows) { + newtGotorc(co->top, co->left); + SLsmg_write_char('\x2d'); + for (i = 1; i < co->height - 1; i++) { + newtGotorc(i + co->top, co->left); + SLsmg_write_char('\x61'); + } + newtGotorc(co->top + co->height - 1, co->left); + SLsmg_write_char('\x2e'); + } else { + for (i = 0; i < co->height; i++) { + newtGotorc(i + co->top, co->left); + SLsmg_write_char('\x61'); + } } SLsmg_set_char_set(0); diff --git a/test.c b/test.c index b7bc965..3e6eed6 100644 --- a/test.c +++ b/test.c @@ -88,7 +88,7 @@ int main(void) { newtFormAddComponents(f, b1, b2, l1, l2, l3, e1, e2, e3, chklist, NULL); newtFormAddComponents(f, rsf, scale, NULL); - lb = newtListbox(45, 1, 4, NEWT_FLAG_MULTIPLE | NEWT_FLAG_BORDER | + lb = newtListbox(45, 1, 6, NEWT_FLAG_MULTIPLE | NEWT_FLAG_BORDER | NEWT_FLAG_SCROLL); newtListboxAppendEntry(lb, "First", (void *) 1); newtListboxAppendEntry(lb, "Second", (void *) 2); @@ -112,14 +112,14 @@ int main(void) { do { answer = newtRunForm(f); - + if (answer == b2) { newtScaleSet(scale, atoi(scaleVal)); newtRefresh(); answer = NULL; } } while (!answer); - + scaleVal = strdup(scaleVal); enr2 = strdup(enr2); enr3 = strdup(enr3); diff --git a/textbox.c b/textbox.c index 358dc3e..8ce1bda 100644 --- a/textbox.c +++ b/textbox.c @@ -345,7 +345,23 @@ static struct eventResult textboxEvent(newtComponent co, break; } } - + if (ev.when == EV_EARLY && ev.event == EV_MOUSE && tb->sb) { + /* Top scroll arrow */ + if (ev.u.mouse.x == co->width && ev.u.mouse.y == co->top) { + if (tb->topLine) tb->topLine--; + textboxDraw(co); + + er.result = ER_SWALLOWED; + } + /* Bottom scroll arrow */ + if (ev.u.mouse.x == co->width && + ev.u.mouse.y == co->top + co->height - 1) { + if (tb->topLine < (tb->numLines - co->height)) tb->topLine++; + textboxDraw(co); + + er.result = ER_SWALLOWED; + } + } return er; } -- 2.47.2