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