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

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

unix.superglobalmegacorp.com

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