Annotation of researchv9/jerq/src/lib/j/menuhit.c, revision 1.1.1.2

1.1       root        1: #include <jerq.h>
1.1.1.2 ! root        2: #include <layer.h>
        !             3: #include <jerqproc.h>
1.1       root        4: #include <font.h>
                      5: 
                      6: #define scale(x, inmin, inmax, outmin, outmax)\
                      7:        (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin))
                      8: 
                      9: #define bound(x, low, high) min(high, max( low, x ))
                     10: 
                     11: #define DISPLAY                16
                     12: #define DELTA          6
                     13: #define BARWIDTH       18
                     14: 
                     15: static char **table;
                     16: static char *
                     17: tablegen(i)
                     18: {
                     19:        return table[i];
                     20: }
                     21: 
                     22: menuhit(m, but)
                     23: register Menu *m;
                     24: {
                     25:        register int width, i, j, top, newtop, hit, newhit, items, lines, length;
                     26:        Point p, q, savep, baro, barc;
                     27:        Rectangle sr, tr, mr;   /* scroll, text, menu */
                     28:        register Bitmap *b;
                     29:        register char *s, *(*generator)(), *from, *to, fill[64];
1.1.1.2 ! root       30: #ifdef MUX
        !            31:        Font *font = (!P||!P->defaultfont)? &defont:
        !            32:                P->defaultfont;
        !            33: #else
        !            34:        Font *font = &defont;
        !            35: #endif MUX
        !            36:        int spacing = font->height;
        !            37:        int charwidth = font->info['n'].width;
1.1       root       38: 
                     39: #define sro sr.origin
                     40: #define src sr.corner
                     41: #define tro tr.origin
                     42: #define trc tr.corner
                     43: #define mro mr.origin
                     44: #define mrc mr.corner
                     45: 
                     46:        generator = (table=m->item) ? tablegen : m->generator;
                     47:        p = mouse.xy;
1.1.1.2 ! root       48:        length = width = items = 0;
        !            49:        for( ; s=(*generator)(items); ++items) {
1.1       root       50:                length = max(length, strlen(s));
1.1.1.2 ! root       51:                width = max(width, strwidth(font,s));
        !            52:        }
1.1       root       53:        if(items == 0){
                     54:                while(button(but));
                     55:                return -1;
                     56:        }
1.1.1.2 ! root       57:        width += 10;
1.1       root       58:        sro.x = sro.y = src.x = tro.x = mro.x = mro.y = 0;
                     59:        if(items <= DISPLAY)
                     60:                lines = items;
                     61:        else{
                     62:                lines = DISPLAY;
                     63:                tro.x = src.x = BARWIDTH;
                     64:                sro.x = sro.y = 1;
                     65:        }
                     66:        tro.y = 1;
1.1.1.2 ! root       67:        mrc = trc = add(Pt(tro.x, mro.y), Pt(width, min(items, lines)*spacing+2));
1.1       root       68:        trc.y = src.y = mrc.y-1;
                     69:        newtop = bound(m->prevtop, 0, items-lines);
1.1.1.2 ! root       70:        p.y -= bound(m->prevhit, 0, lines-1)*spacing+spacing/2;
1.1       root       71:        p.x = bound(p.x-(src.x+width/2), 0, XMAX-mrc.x);
                     72:        p.y = bound(p.y, 0, YMAX-mrc.y);
                     73:        sr = raddp(sr, p);
                     74:        tr = raddp(tr, p);
                     75:        mr = raddp(mr, p);
                     76:        b = balloc(mr);
                     77:        cursinhibit();
                     78:        if(b)
                     79:                bitblt(&display, mr, b, mro, F_STORE);
                     80:        rectf(&display, mr, F_OR);
                     81:        cursallow();
                     82: PaintMenu:
                     83:        cursinhibit();
                     84:        rectf(&display, inset(mr, 1), F_CLR);
                     85:        cursallow();
                     86:        top = newtop;
                     87:        if(items > DISPLAY){
                     88:                baro.y = scale(top, 0, items, sro.y, src.y);
                     89:                baro.x = sr.origin.x;
                     90:                barc.y = scale(top+DISPLAY, 0, items, sro.y, src.y);
                     91:                barc.x = sr.corner.x;
                     92:                rectf(&display, Rpt(baro,barc), F_XOR);
                     93:        }
                     94:        for(p=tro, i=top; i < min(top+lines, items); ++i){
                     95:                q = p;
                     96:                from = generator(i);
                     97:                for(to = &fill[0]; *from; ++from)
                     98:                        if(*from & 0x80)
                     99:                                for(j=length-(strlen(from+1)+(to-&fill[0])); j-->0;)
                    100:                                        *to++ = *from & 0x7F;
                    101:                        else
                    102:                                *to++ = *from;
                    103:                *to = '\0';
1.1.1.2 ! root      104:                q.x += (width-strwidth(font,fill))/2;
        !           105:                string(font, fill, &display, q, F_XOR);
        !           106:                p.y += spacing;
1.1       root      107:        }
                    108:        savep = mouse.xy;
                    109:        for(newhit = hit = -1; button(but); nap(2)){
                    110:                if(ptinrect(p = mouse.xy, sr)){
                    111:                        if(ptinrect(savep,tr)){
                    112:                                p.y = (baro.y+barc.y)/2;
                    113:                                cursset(p);
                    114:                        }
                    115:                        newtop = scale(p.y, sro.y, src.y, 0, items);
                    116:                        newtop = bound(newtop-DISPLAY/2, 0, items-DISPLAY);
                    117:                        if(newtop != top)
                    118: /* ->->-> */                   goto PaintMenu;
                    119:                }else if(ptinrect(savep,sr)){
                    120:                        register dx, dy;
                    121:                        if(abs(dx = p.x-savep.x) < DELTA)
                    122:                                dx = 0;
                    123:                        if(abs(dy = p.y-savep.y) < DELTA)
                    124:                                dy = 0;
                    125:                        if(abs(dy) >= abs(dx))
                    126:                                dx = 0;
                    127:                        else
                    128:                                dy = 0;
                    129:                        cursset(p = add(savep, Pt(dx,dy)));
                    130:                }
                    131:                savep = p;
                    132:                newhit = -1;
                    133:                if(ptinrect(p, tr)){
1.1.1.2 ! root      134:                        newhit = bound((p.y-tro.y)/spacing, 0, lines-1);
1.1       root      135:                        if(newhit!=hit && hit>=0
1.1.1.2 ! root      136:                         && abs(tro.y+spacing*newhit+spacing/2-p.y) > spacing/3)
1.1       root      137:                                newhit = hit;
                    138:                }
                    139:                if(newhit != hit){
1.1.1.2 ! root      140:                        flip(tr, hit, spacing);
        !           141:                        flip(tr, hit = newhit, spacing);
1.1       root      142:                }
                    143:                if(newhit==0 && top>0){
                    144:                        newtop = top-1;
1.1.1.2 ! root      145:                        p.y += spacing;
1.1       root      146:                        cursset(p);
                    147: /* ->->-> */           goto PaintMenu;
                    148:                }
                    149:                if(newhit==DISPLAY-1 && top<items-lines){
                    150:                        newtop = top+1;
1.1.1.2 ! root      151:                        p.y -= spacing;
1.1       root      152:                        cursset(p);
                    153: /* ->->-> */           goto PaintMenu;
                    154:                }
                    155:        }
                    156:        if(b){
                    157:                cursinhibit();
                    158:                screenswap(b, b->rect, b->rect);
                    159:                cursallow();
                    160:                bfree(b);
                    161:        }
                    162:        if(hit>=0){
                    163:                m->prevhit = hit;
                    164:                m->prevtop = top;
                    165:                return hit+top;
                    166:        }else
                    167:                return -1;
                    168: }
                    169: 
                    170: static
1.1.1.2 ! root      171: flip(r,n,spacing)
1.1       root      172:        Rectangle r;
                    173: {
                    174:        if(n<0)
                    175:                return;
                    176:        ++r.origin.x;
1.1.1.2 ! root      177:        r.corner.y = (r.origin.y += spacing*n) + spacing;
1.1       root      178:        --r.corner.x;
                    179:        rectf(&display, r, F_XOR);
                    180: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.