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