#include #include #include #include "m.h" extern Mouse mouse; enum{ Margin=3, /* outside to text */ Border=2, /* outside to selection boxes */ Blackborder=1, /* width of outlining border */ Vspacing=1 /* extra spacing between lines of text */ }; Rectangle menurect(Rectangle, int); int menusel(Rectangle r, Point p); extern void cursorset(Point p); int mymenuhit(int but, Menu *menu) { int i, nitem, maxwid=0, lasti; Rectangle r, menur; Point pt; Bitmap *b; char *item; for(nitem=0; item=menu->item? menu->item[nitem] : (*menu->gen)(nitem); nitem++){ i=strwidth(font, item); if(i>maxwid) maxwid=i; } if(menu->lasthit<0 || menu->lasthit>=nitem) menu->lasthit=0; r=inset(Rect(0, 0, maxwid, nitem*(font->height+Vspacing)), -Margin); r=rsubp(r, Pt(maxwid/2, menu->lasthit*(font->height+Vspacing)+font->height/2)); r=raddp(r, mouse.xy); pt=Pt(0, 0); if(r.max.x>screen.r.max.x) pt.x=screen.r.max.x-r.max.x; if(r.max.y>screen.r.max.y) pt.y=screen.r.max.y-r.max.y; if(r.min.xheight+Vspacing){ item=menu->item? menu->item[i] : (*menu->gen)(i); string(&screen, Pt((pt.x-strwidth(font, item))/2, pt.y), font, item, S); } lasti=-1; r=menurect(menur, menu->lasthit); cursorset(div(add(r.min, r.max), 2)); bitblt(&screen, r.min, &screen, r, F&~D); while(mouse.buttons&(1<<(but-1))){ getmouse(); i=menusel(menur, mouse.xy); if(i==lasti) continue; bitblt(&screen, r.min, &screen, r, F&~D); r=menurect(menur, i); bitblt(&screen, r.min, &screen, r, F&~D); lasti=i; } bitblt(&screen, menur.min, b, menur, S); if(b != &screen) bfree(b); return menu->lasthit=lasti; } Rectangle menurect(Rectangle r, int i) { if(i<0) return Rect(0, 0, 0, 0); r=inset(r, Margin); r.min.y+=(font->height+Vspacing)*i; r.max.y=r.min.y+font->height+Vspacing; return inset(r, Border-Margin); } int menusel(Rectangle r, Point p) { r=inset(r, Margin); if(!ptinrect(p, r)) return -1; return (p.y-r.min.y)/(font->height+Vspacing); }