Annotation of researchv9/jtools/src/pads/x11/scripthit.c, revision 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.