Annotation of researchv9/jtools/src/pads/x11/scripthit.c, revision 1.1.1.1

1.1       root        1: #include "univ.h"
                      2: 
                      3: #define scale( x, inmin, inmax, outmin, outmax )\
                      4:        ( outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin) )
                      5: 
                      6: #define bound( x, low, high ) ( min( high, max( low, x ) ) )
                      7: 
                      8: #define SPACING                fontheight(&defont)
                      9: #define DISPLAY                13
                     10: #define CHARWIDTH      fontwidth(&defont)
                     11: 
                     12: #define DELTA          6
                     13: #define BARWIDTH       18
                     14: 
                     15: int MenuNest;
                     16: 
                     17: Entry *EntryGen(i, s)
                     18: register Script *s;
                     19: {
                     20:        register Entry *e;
                     21: 
                     22:        for( ; s; s = s->more ){
                     23:                CIndex = s->cindex;
                     24:                if( i < s->items )
                     25:                        return (s->generator)(i);
                     26:                i -= s->items;
                     27:        }
                     28:        return 0;
                     29: }
                     30: 
                     31: Limits(s)
                     32: register Script *s;
                     33: {
                     34:        register i, l;
                     35:        register Entry *e;
                     36: 
                     37:        s->items = s->width = 0;
                     38:        for( i = 0; e = (s->generator)(i); ++i ){
                     39:                ++s->items;
                     40:                l = strlen(e->text);
                     41:                if( l > s->width ) s->width = l;
                     42:        }
                     43: }
                     44: 
                     45: Entry *ScriptHit(sh, but, rl)
                     46: register Script *sh;
                     47: RectList *rl;
                     48: {
                     49:        register int width, i, j, top, newtop, hit, newhit, items, lines, charswide;
                     50:        Point p, q, savep, baro, barc;
                     51:        Rectangle sr, tr, mr;   /* scroll, text, menu */
                     52:        register Bitmap *b;
                     53:        register char *s, *from, *to, fill[64];
                     54:        register Script *m;
                     55:        register Entry *e;
                     56:        RectList lrl, *l;
                     57: 
                     58: #define sro sr.origin
                     59: #define src sr.corner
                     60: #define tro tr.origin
                     61: #define trc tr.corner
                     62: #define mro mr.origin
                     63: #define mrc mr.corner
                     64: 
                     65:        charswide = items = 0;
                     66:        for( m = sh; m; m = m->more ){
                     67:                CIndex = m->cindex;
                     68:                m->items = m->width = 0;
                     69:                if( m->limits )
                     70:                        m->limits(m);
                     71:                else
                     72:                        Limits(m);
                     73:                items += m->items;
                     74:                if( m->width > charswide ){
                     75:                        charswide = m->width;
                     76:                        if( charswide >= sizeof(fill) )
                     77:                                charswide = sizeof(fill) - 1;
                     78:                }
                     79:        }
                     80:        p = mouse.xy;
                     81:        if( items == 0 ) return 0;
                     82:        width = charswide*CHARWIDTH+10;
                     83:        sro.x = sro.y = src.x = tro.x = mro.x = mro.y = 0;
                     84:        if( items <= DISPLAY ) lines = items;
                     85:        else {
                     86:                lines = DISPLAY;
                     87:                tro.x = src.x = BARWIDTH;
                     88:                sro.x = sro.y = 1;
                     89:        }
                     90: #define ASCEND 2
                     91:        tro.y = ASCEND;
                     92:        mrc = trc = add(tro, Pt(width,min(items,lines)*SPACING) );
                     93:        src.y = mrc.y-1;
                     94:        newtop = bound(sh->prevtop, 0, items-lines );
                     95:        p.y -= bound(sh->prevhit, 0, lines-1)*SPACING+SPACING/2;
                     96:        p.x = bound(p.x-(src.x+width/2), 0, display.rect.corner.x-mrc.x);
                     97:        p.y = bound(p.y, 0, display.rect.corner.y-mrc.y);
                     98:        sr = raddp(sr,p);
                     99:        tr = raddp(tr, p);
                    100:        mr = raddp(mr, p);
                    101:        b = balloc(mr);
                    102:        if( b ) bitblt(&display, mr, b, mro, F_STORE);
                    103:        rectf( &display, mr, F_STORE );
                    104: PaintMenu:
                    105:        rectf( &display, inset(mr,1), F_CLR );
                    106:        top = newtop;
                    107:        if( items > DISPLAY ){
                    108:                baro.y = scale(top, 0, items, sro.y, src.y);
                    109:                baro.x = sr.origin.x;
                    110:                barc.y = scale(top+DISPLAY, 0, items, sro.y, src.y);
                    111:                barc.x = sr.corner.x;
                    112:                rectf(&display, Rpt(baro,barc), F_XOR);
                    113:        }
                    114:        for( p = tro, i = top; i < min(top+lines,items); ++i ){
                    115:                q = p;
                    116:                e = EntryGen(i, sh);
                    117:                from = e->text;
                    118:                for( to = &fill[0]; *from; ++from ){
                    119:                        if( *from & 0x80 )
                    120:                                for(j=charswide-(strlen(from+1)+(to-&fill[0])); j-->0;)
                    121:                                        *to++ = *from & 0x7F;
                    122:                        else
                    123:                                *to++ = *from;
                    124:                }
                    125:                if( e->script ){
                    126:                        static Bitmap *bb;
                    127:                        Point qq;
                    128:                        qq.y = q.y+1;
                    129:                        qq.x = q.x+width-15;
                    130:                        if( !bb ){
                    131:                                bb = balloc(Rect(0,0,15,15));
                    132:                                assert(bb);
                    133:                                texture(bb, bb->rect, &Arrow, F_STORE);
                    134:                        }
                    135:                        bitblt(bb, bb->rect, &display, qq, F_XOR);
                    136:                }
                    137:                *to = '\0';
                    138:                q.x += ( width-strwidth(&defont, fill) )/2;
                    139:                string( &defont, fill, &display, q, F_XOR );
                    140:                p.y += SPACING;
                    141:        }
                    142:        savep = mouse.xy;
                    143:        newhit = hit = -1;
                    144:        e = 0;
                    145:        for( ; button(but); jnap(2) ){
                    146:                p = mouse.xy;
                    147:                if( ptinrect(p, sr) ){
                    148:                        if( ptinrect(savep,tr) ){
                    149:                                p.y = (baro.y+barc.y)/2;
                    150:                                cursset( p );
                    151:                        }
                    152:                        newtop = scale( p.y, sro.y, src.y, 0, items );
                    153:                        newtop = bound( newtop-DISPLAY/2, 0, items-DISPLAY );
                    154:                        if( newtop != top )
                    155:                                goto PaintMenu;
                    156:                } 
                    157:                savep = p;
                    158:                newhit = -1;
                    159:                if( ptinrect(p, tr) ){
                    160:                        newhit = bound((p.y-tro.y)/SPACING, 0, lines-1);
                    161:                        if( hit >= 0
                    162:                         && abs(tro.y+SPACING*newhit+SPACING/2-p.y) > SPACING/3 )
                    163:                                newhit = hit;
                    164:                }
                    165:                if( newhit != hit ){
                    166:                        flip(tr, hit);
                    167:                        flip(tr, hit = newhit);
                    168:                        e = hit>=0 ? EntryGen(hit+top, sh) : 0;
                    169:                }
                    170:                if( !ptinrect(p, mr) ){
                    171:                        assert(!e);
                    172:                        for( l = rl; l; l = l->more )
                    173:                                if( ptinrect(p, *l->rp) )
                    174:                                        goto Done;
                    175:                }
                    176:                if(newhit==0 && top>0){
                    177:                        newtop = top-1;
                    178:                        p.y += SPACING;
                    179:                        cursset(p);
                    180:                        goto PaintMenu;
                    181:                }
                    182:                if(newhit==DISPLAY-1 && top<items-lines){
                    183:                        newtop = top+1;
                    184:                        p.y -= SPACING;
                    185:                        cursset(p);
                    186:                        goto PaintMenu;
                    187:                }
                    188:                if( e && e->script
                    189:                 && p.x > trc.x-CHARWIDTH ){
                    190:                        p.x = trc.x;
                    191:                        cursset(p);
                    192:                        lrl.rp = &mr;
                    193:                        lrl.more = rl;
                    194:                        ++MenuNest;
                    195:                        e = ScriptHit(e->script, but, &lrl);
                    196:                        --MenuNest;
                    197:                        if( e ) goto Done;
                    198:                        goto PaintMenu;
                    199:                }
                    200:        }
                    201: Done:
                    202:        if( b ){
                    203:                bitblt(b, b->rect, &display, b->rect.origin, F_STORE);
                    204:                bfree(b);
                    205:        }
                    206:        jerqsync();
                    207:        sh->prevhit = hit;
                    208:        sh->prevtop = top;
                    209:        return e;
                    210: }
                    211: 
                    212: static flip(r,n)
                    213: Rectangle r;
                    214: {
                    215:        if( n<0 ) return;
                    216:        ++r.origin.x;
                    217:        r.corner.y = (r.origin.y += SPACING*n-1) + SPACING;
                    218:        --r.corner.x;
                    219:        rectf( &display, r, F_XOR );
                    220: }

unix.superglobalmegacorp.com

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