Annotation of researchv9/jtools/src/sunlib/mhit.c, revision 1.1

1.1     ! root        1: #include       "jerq.h"
        !             2: #include       "menu.h"
        !             3: #define                disp Jfscreen
        !             4: 
        !             5: #ifdef SUNTOOLS
        !             6: #undef F_STORE
        !             7: #define        F_STORE (PIX_DONTCLIP|PIX_SRC)
        !             8: #define        F_NCXOR (PIX_DONTCLIP|(PIX_SRC ^ PIX_DST))
        !             9: #else
        !            10: #define        F_NCXOR F_XOR
        !            11: #endif SUNTOOLS
        !            12: 
        !            13: static screenswap (bp, rect, screenrect)
        !            14: register Bitmap *bp;
        !            15: Rectangle rect;
        !            16: Rectangle screenrect;
        !            17: {
        !            18:        bitblt(&disp, screenrect, bp, rect.origin, F_NCXOR);
        !            19:        bitblt(bp, rect, &disp, screenrect.origin, F_NCXOR);
        !            20:        bitblt(&disp, screenrect, bp, rect.origin, F_NCXOR);
        !            21: }
        !            22: 
        !            23: #define scale(x, inmin, inmax, outmin, outmax)\
        !            24:        (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin))
        !            25: 
        !            26: #define bound(x, low, high) min(high, max( low, x ))
        !            27: 
        !            28: Font *font = &defont;
        !            29: #define SPACING                (1+fontheight(font))
        !            30: #define CHARWIDTH      fontwidth(font)
        !            31: #define DISPLAY                16
        !            32: #define DELTA          6
        !            33: #define BARWIDTH       18
        !            34: #define        MAXDEPTH        16      /* don't use too much stack */
        !            35: #define ARROWIDTH      20
        !            36: 
        !            37: static short tarrow_bits[] =
        !            38: {
        !            39:        0x0000, 0x0000, 0x0080, 0x00C0, 0x00C0, 0x00E0, 0x00F8, 0xFFFE,
        !            40:        0xFFFE, 0x00F8, 0x00E0, 0x00C0, 0x00C0, 0x0080, 0x0000, 0x0000,
        !            41: };
        !            42: static Texture tarrow;
        !            43: static int firstime = 1;
        !            44: 
        !            45: static NMitem *
        !            46: tablegen(i, table)
        !            47: NMitem *table;
        !            48: {
        !            49:        return &table[i];
        !            50: }
        !            51: 
        !            52: static char fill[64];
        !            53: 
        !            54: NMitem *
        !            55: mhit(m, but, depth)
        !            56: register NMenu *m;
        !            57: {
        !            58:        register int width, mwidth, i, j, top, newtop, hit, newhit;
        !            59:        register int items, lines, length, w, x;
        !            60:        Point p, q, savep, baro, barc;
        !            61:        Rectangle sr, tr, mr;   /* scroll, text, menu */
        !            62:        Rectangle rside, rhit;
        !            63:        register Bitmap *b;
        !            64:        register char *from, *to;
        !            65:        Bitmap *bhelp = 0, *arrow;
        !            66:        NMitem *(*generator)(), *mi, *table, *ret = 0;
        !            67:        int dohfn;
        !            68: 
        !            69: #define sro sr.origin
        !            70: #define src sr.corner
        !            71: #define tro tr.origin
        !            72: #define trc tr.corner
        !            73: #define mro mr.origin
        !            74: #define mrc mr.corner
        !            75: 
        !            76:        if (firstime) {
        !            77:                firstime = 0;
        !            78:                tarrow = ToTexture(tarrow_bits);
        !            79:        }
        !            80:        generator = (table=m->item) ? tablegen : m->generator;
        !            81:        arrow = balloc(Rect(0, 0, 16, 16));
        !            82:        texture(arrow, arrow->rect, &tarrow, F_STORE);
        !            83:        w = x = length = 0;
        !            84:        for(items = 0; (mi=(*generator)(items, table))->text; ++items) {
        !            85:                register int s = strlen (mi->text);
        !            86:                length = max(length, s);
        !            87:                if (mi->next) {
        !            88:                        w = max (w, s);
        !            89:                } else
        !            90:                        x = max (x, s);
        !            91:        }
        !            92:        if(items == 0)
        !            93:                return(ret);
        !            94:        Jscreengrab();
        !            95:        width = length*CHARWIDTH+10;
        !            96:        w *= CHARWIDTH;
        !            97:        x *= CHARWIDTH;
        !            98:        if (x <= w)
        !            99:                mwidth = w + ARROWIDTH;
        !           100:        else if (x >= w + 2*ARROWIDTH)
        !           101:                mwidth = x;
        !           102:        else
        !           103:                mwidth = w + ARROWIDTH + (x - w) / 2;
        !           104:        mwidth += 10;
        !           105:        sro.x = sro.y = src.x = tro.x = mro.x = mro.y = 0;
        !           106:        if(items <= DISPLAY)
        !           107:                lines = items;
        !           108:        else{
        !           109:                lines = DISPLAY;
        !           110:                tro.x = src.x = BARWIDTH;
        !           111:                sro.x = sro.y = 1;
        !           112:        }
        !           113: #define ASCEND 2
        !           114:        tro.y = ASCEND;
        !           115:        mrc = trc = add(tro, Pt(mwidth, min(items, lines)*SPACING));
        !           116:        src.y = mrc.y-1;
        !           117:        newtop = bound(m->prevtop, 0, items-lines);
        !           118:        p = add(mouse.xy, Joffset);
        !           119:        p.y -= bound(m->prevhit, 0, lines-1)*SPACING+SPACING/2;
        !           120:        p.x = bound(p.x-(src.x+mwidth/2), Jfscreen.rect.origin.x,
        !           121:                Jfscreen.rect.corner.x-mrc.x);
        !           122:        p.y = bound(p.y, Jfscreen.rect.origin.y, Jfscreen.rect.corner.y-mrc.y);
        !           123:        sr = raddp(sr, p);
        !           124:        tr = raddp(tr, p);
        !           125:        mr = raddp(mr, p);
        !           126:        rside = mr;
        !           127:        rside.origin.x = rside.corner.x-20;
        !           128:        b = balloc(mr);
        !           129:        cursinhibit();
        !           130:        if(b)
        !           131:                bitblt(&disp, mr, b, mro, F_STORE);
        !           132:        rectf(&disp, mr, F_OR);
        !           133:        cursallow();
        !           134: PaintMenu:
        !           135:        cursinhibit();
        !           136:        rectf(&disp, inset(mr, 1), F_CLR);
        !           137:        cursallow();
        !           138:        top = newtop;
        !           139:        if(items > DISPLAY){
        !           140:                baro.y = scale(top, 0, items, sro.y, src.y);
        !           141:                baro.x = sr.origin.x;
        !           142:                barc.y = scale(top+DISPLAY, 0, items, sro.y, src.y);
        !           143:                barc.x = sr.corner.x;
        !           144:                rectf(&disp, Rpt(baro,barc), F_XOR);
        !           145:        }
        !           146:        for(p=tro, i=top; i < min(top+lines, items); ++i){
        !           147:                q = p;
        !           148:                mi = generator(i, table);
        !           149:                from = mi->text;
        !           150:                for(to = &fill[0]; *from; ++from)
        !           151:                        if(*from & 0x80)
        !           152:                                for(j=length-(strlen(from+1)+(to-&fill[0])); j-->0;)
        !           153:                                        *to++ = *from & 0x7F;
        !           154:                        else
        !           155:                                *to++ = *from;
        !           156:                *to = '\0';
        !           157:                q.x += (width-strwidth(font,fill))/2;
        !           158:                string(&defont, fill, &disp, q, F_XOR);
        !           159:                if(mi->next)
        !           160:                        bitblt(arrow, arrow->rect, &disp, Pt(trc.x-18, p.y-2), F_OR);
        !           161:                p.y += SPACING;
        !           162:        }
        !           163:        savep = add(mouse.xy, Joffset);
        !           164:        mi = 0;
        !           165:        for(newhit = hit = -1; button(but); ){
        !           166:                p = add(mouse.xy, Joffset);
        !           167:                if(depth && ((p.x < mro.x) || button(5-but)))
        !           168:                {
        !           169:                        ret = 0;
        !           170:                        break;
        !           171:                }
        !           172:                if(ptinrect(p, sr)){
        !           173:                        if(ptinrect(savep,tr)){
        !           174:                                p.y = (baro.y+barc.y)/2;
        !           175:                                cursset(sub(p,Joffset));
        !           176:                        }
        !           177:                        newtop = scale(p.y, sro.y, src.y, 0, items);
        !           178:                        newtop = bound(newtop-DISPLAY/2, 0, items-DISPLAY);
        !           179:                        if(newtop != top)
        !           180: /* ->->-> */                   goto PaintMenu;
        !           181:                }else if(ptinrect(savep,sr)){
        !           182:                        register dx, dy;
        !           183:                        if(abs(dx = p.x-savep.x) < DELTA)
        !           184:                                dx = 0;
        !           185:                        if(abs(dy = p.y-savep.y) < DELTA)
        !           186:                                dy = 0;
        !           187:                        if(abs(dy) >= abs(dx))
        !           188:                                dx = 0;
        !           189:                        else
        !           190:                                dy = 0;
        !           191:                        p = add(savep, Pt(dx,dy));
        !           192:                        cursset(sub(p,Joffset));
        !           193:                }
        !           194:                savep = p;
        !           195:                newhit = -1;
        !           196:                if(ptinrect(p, tr)){
        !           197:                        newhit = bound((p.y-tro.y)/SPACING, 0, lines-1);
        !           198:                        if(newhit!=hit && hit>=0
        !           199:                         && abs(tro.y+SPACING*newhit+SPACING/2-p.y) > SPACING/3)
        !           200:                                newhit = hit;
        !           201:                        rhit = tr;
        !           202:                        rhit.origin.y += newhit*SPACING-ASCEND/2;
        !           203:                        rhit.corner.y = rhit.origin.y + SPACING;
        !           204:                }
        !           205:                if(newhit == -1)
        !           206:                        ret = 0, dohfn = 0;
        !           207:                else
        !           208:                        ret = mi = (*generator)(top+newhit, table), dohfn = 1;
        !           209:                if(newhit == hit)
        !           210:                {
        !           211:                        if((newhit != -1) && (bhelp == 0) && button1() && mi->help)
        !           212:                                helpon(mi->help, rhit, &bhelp);
        !           213:                        else if(bhelp && !button1())
        !           214:                                helpoff(&bhelp);
        !           215:                }
        !           216:                else
        !           217:                {
        !           218:                        flip(tr, hit);
        !           219:                        helpoff(&bhelp);
        !           220:                        flip(tr, newhit);
        !           221:                        hit = newhit;
        !           222:                        if((newhit != -1) && button1() && mi->help)
        !           223:                                helpon(mi->help, rhit, &bhelp);
        !           224:                }
        !           225:                if((newhit != -1) && ptinrect(p, rside))
        !           226:                {
        !           227:                        if(mi->dfn) (*mi->dfn)(mi);
        !           228:                        if(mi->next && (depth <= MAXDEPTH))
        !           229:                                ret = mhit(mi->next, but, depth+1), dohfn = 0;
        !           230:                        if(mi->bfn) (*mi->bfn)(mi);
        !           231:                }
        !           232:                if(newhit==0 && top>0){
        !           233:                        newtop = top-1;
        !           234:                        p.y += SPACING;
        !           235:                        cursset(sub(p,Joffset));
        !           236: /* ->->-> */           goto PaintMenu;
        !           237:                }
        !           238:                if(newhit==DISPLAY-1 && top<items-lines){
        !           239:                        newtop = top+1;
        !           240:                        p.y -= SPACING;
        !           241:                        cursset(sub(p,Joffset));
        !           242: /* ->->-> */           goto PaintMenu;
        !           243:                }
        !           244:                if (button(but))
        !           245:                        nap(2);
        !           246:        }
        !           247:        if(bhelp)
        !           248:                helpoff(&bhelp);
        !           249:        if(b){
        !           250:                cursinhibit();
        !           251:                screenswap(b, b->rect, b->rect);
        !           252:                cursallow();
        !           253:                bfree(b);
        !           254:        }
        !           255:        if(hit>=0){
        !           256:                m->prevhit = hit;
        !           257:                m->prevtop = top;
        !           258:                if(ret && ret->hfn && dohfn) (*ret->hfn)(mi);
        !           259:        }
        !           260:        Jscreenrelease();
        !           261:        return(ret);
        !           262: }
        !           263: 
        !           264: static
        !           265: flip(r,n)
        !           266:        Rectangle r;
        !           267: {
        !           268:        if(n<0)
        !           269:                return;
        !           270:        ++r.origin.x;
        !           271:        r.corner.y = (r.origin.y += SPACING*n-1) + SPACING;
        !           272:        --r.corner.x;
        !           273:        rectf(&disp, r, F_XOR);
        !           274: }
        !           275: 
        !           276: static
        !           277: helpon(msg, r, bhelp)
        !           278:        char *msg;
        !           279:        Rectangle r;
        !           280:        Bitmap **bhelp;
        !           281: {
        !           282:        register Bitmap *b;
        !           283:        register w;
        !           284: 
        !           285:        w = strwidth(&defont, msg)+10;
        !           286:        if(r.corner.x+w < disp.rect.corner.x){
        !           287:                r.origin.x = r.corner.x;
        !           288:                r.corner.x += w;
        !           289:        }
        !           290:        else{
        !           291:                r.corner.x = r.origin.x;
        !           292:                r.origin.x -= w;
        !           293:        }
        !           294:        if(*bhelp = b = balloc(r = inset(r, -1))){
        !           295:                rectf(b, r, F_OR);
        !           296:                rectf(b, inset(r, 1), F_XOR);
        !           297:                string(&defont, msg, b, add(b->rect.origin, Pt(5, 1)),F_XOR);
        !           298:                screenswap(b, b->rect, b->rect);
        !           299:        }
        !           300: }
        !           301: 
        !           302: static
        !           303: helpoff (bhelp)
        !           304: Bitmap **bhelp;
        !           305: {
        !           306:        Bitmap *bh;
        !           307: 
        !           308:        if(bh = *bhelp){
        !           309:                screenswap(bh, bh->rect, bh->rect);
        !           310:                bfree(bh);
        !           311:                *bhelp = 0;
        !           312:        }
        !           313: }

unix.superglobalmegacorp.com

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