]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
Mouse support
authormsw <msw>
Thu, 7 Jan 1999 05:19:55 +0000 (05:19 +0000)
committermsw <msw>
Thu, 7 Jan 1999 05:19:55 +0000 (05:19 +0000)
13 files changed:
.cvsignore
CHANGES
button.c
checkbox.c
entry.c
form.c
listbox.c
newt.c
newt.spec
newt_pr.h
scrollbar.c
test.c
textbox.c

index 729e18eaa2149c586d05a597168e19ef41eabaa6..372438120a637a1e33afd850beff4843f21ab6f8 100644 (file)
@@ -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 fcfdc4c43411fa7a5955f54e11340ffbcccc780c..2edad3c3e794c97106714490e3770945a4e19fc6 100644 (file)
--- 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
 
index f1a35930b415ceda64675e0c0977b77a6e45da13..ec977878dc5b99f74f32c6372221e1d3004d4215 100644 (file)
--- 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;
index 80aeb900257be4c29ff8f45f95acf8b4a71a5f19..785c17f65fffd693ed9c0eef0baada5641f840dd 100644 (file)
@@ -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 e5dabd5a40adc44ff9aeafbdc94fb5c6060f9e09..a44c63f2e601ba6f17e3b3d2722201e4cda4088e 100644 (file)
--- 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 c9b1aa0022eb0292e739d3c5f60a78364cdd2284..66cc6314464b79bd9d4da0da0330c8def51f1ff5 100644 (file)
--- a/form.c
+++ b/form.c
@@ -1,14 +1,20 @@
+#include "config.h"
+
 #include <slang.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <sys/select.h>
 
+#ifdef HAVE_LIBGPM
+#include <gpm.h>
+#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;
index 051c7a6ee42a3866d84790f120d096b10778d0d1..4363cfbfde1470ce3333b3cad00dc947ad4ef201 100644 (file)
--- 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 2e2085dd4ad659f2a437d5de2bd848c3adf46a29..7f1fd56ec4d6113c52889f2ba16bf15835e0e0d8 100644 (file)
--- 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 =
 "  <Tab>/<Alt-Tab> between elements   |  <Space> selects   |  <F12> 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;
index a488067ef603d2f12477027e8686f40e86b7cf2a..728bbda78c2e24ce2b07a9a226acf799aac0e51d 100644 (file)
--- a/newt.spec
+++ b/newt.spec
@@ -33,6 +33,7 @@ widgets and stackable windows.
 %setup
 
 %build
+./configure
 make
 make shared
 
index 5a5e21e128764f5aea7d8b24fe587e908eecaa08..76f5e2f6fda621e1949fae129e906fa1f025c8e1 100644 (file)
--- 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;
 } ;
 
index 5235d7a65a4c2f3c38483e9d24d136e9583da6b0..cb4bc27578a69c6be0639ae41ce4b7436bd2c100 100644 (file)
@@ -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 b7bc965acb6df61d23df7673e8a74c9c971c2e5e..3e6eed6c0cc48bd3e6e67452359a1bf2527edb37 100644 (file)
--- 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);
index 358dc3e3859a62ff59c8e09d8a0197036694f031..8ce1bda79ac874b21baf993cdcb7613843d0a5e9 100644 (file)
--- 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;
 }