void duplicate(Flayer *l, Rectangle r, XftFont *f, int close) { Text *t=(Text *)l->user1; Flayer *nl = findl(t); Rune *rp; ulong n; if(nl){ flnew(nl, stgettext, l->user0, (char *)t); flinit(nl, r, f); nl->origin = l->origin; rp = (*l->textfn)(l, l->f.nchars, &n); flinsert(nl, rp, rp+n, l->origin); flsetselect(nl, l->p0, l->p1); if(close){ flclose(l); if(l==which) which = 0; }else t->nwin++; current(nl); hcheck(t->tag); } cursorswitch(cursor); }
void menu3hit(void) { Rectangle r; Flayer *l; int m, i; Text *t; mw = -1; switch(m = menuhit(3, &mouse, &menu3)){ case -1: break; case New: if(!lock) sweeptext(1, 0); break; case Xerox: case Reshape: if(!lock){ cursorswitch(&bullseye); buttons(Down); if((mouse.buttons&4) && (l = flwhich(mouse.xy)) && getr(&r)) duplicate(l, r, l->f.font, m==Reshape); else cursorswitch(cursor); buttons(Up); } break; case Close: if(!lock){ cursorswitch(&bullseye); buttons(Down); if((mouse.buttons&4) && (l = flwhich(mouse.xy)) && !lock){ t=(Text *)l->user1; if (t->nwin>1) closeup(l); else if(t!=&cmd) { outTs(Tclose, t->tag); setlock(); } } cursorswitch(cursor); buttons(Up); } break; case Write: if(!lock){ cursorswitch(&bullseye); buttons(Down); if((mouse.buttons&4) && (l = flwhich(mouse.xy))){ outTs(Twrite, ((Text *)l->user1)->tag); setlock(); }else cursorswitch(cursor); buttons(Up); } break; default: if(t = text[m-NMENU3]){ i = t->front; if(t->nwin==0 || t->l[i].textfn==0) return; /* not ready yet; try again later */ if(t->nwin>1 && which==&t->l[i]) do if(++i==NL) i = 0; while(i!=t->front && t->l[i].textfn==0); current(&t->l[i]); }else if(!lock) sweeptext(0, tag[m-NMENU3]); break; } }
int menuhit(int but, Mouse *m, Menu *menu) { int i, nitem, nitemdrawn, maxwid, lasti, off, noff, wid, screenitem; bool scrolling; Rectangle r, menur, sc, textr, scrollr; Bitmap *b; Point pt; char *item; extern unsigned int cursor; unsigned int oldcursor = cursor; cursorswitch(ArrowCursor); sc = screen.clipr; clipr(&screen, screen.r); maxwid = 0; 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; screenitem = (Dy(screen.r)-10)/(fontheight()+Vspacing); if(nitem>Maxunscroll || nitem>screenitem){ scrolling = true; nitemdrawn = Nscroll; if(nitemdrawn > screenitem) nitemdrawn = screenitem; wid = maxwid + Gap + Scrollwid; off = menu->lasthit - nitemdrawn/2; if(off < 0) off = 0; if(off > nitem-nitemdrawn) off = nitem-nitemdrawn; lasti = menu->lasthit-off; }else{ scrolling = false; nitemdrawn = nitem; wid = maxwid; off = 0; lasti = menu->lasthit; } r = inset(Rect(0, 0, wid, nitemdrawn*(fontheight()+Vspacing)), -Margin); r = rsubp(r, Pt(wid/2, lasti*(fontheight()+Vspacing)+fontheight()/2)); r = raddp(r, m->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.x<screen.r.min.x) pt.x = screen.r.min.x-r.min.x; if(r.min.y<screen.r.min.y) pt.y = screen.r.min.y-r.min.y; menur = raddp(r, pt); textr.max.x = menur.max.x-Margin; textr.min.x = textr.max.x-maxwid; textr.min.y = menur.min.y+Margin; textr.max.y = textr.min.y + nitemdrawn*(fontheight()+Vspacing); if(scrolling){ scrollr = inset(menur, Border); scrollr.max.x = scrollr.min.x+Scrollwid; }else scrollr = Rect(0, 0, 0, 0); b = balloc(menur, screen.ldepth); if(b == 0) b = &screen; bitblt(b, menur.min, &screen, menur, S); bitblt(&screen, menur.min, &screen, menur, 0); border(&screen, menur, Blackborder, F, _bgpixel); r = menurect(textr, lasti); cursorset(divpt(add(r.min, r.max), 2)); menupaint(menu, textr, off, nitemdrawn); if(scrolling) menuscrollpaint(scrollr, off, nitem, nitemdrawn); r = menurect(textr, lasti); cursorset(divpt(add(r.min, r.max), 2)); menupaint(menu, textr, off, nitemdrawn); if(scrolling) menuscrollpaint(scrollr, off, nitem, nitemdrawn); while(m->buttons & (1<<(but-1))){ lasti = menuscan(but, m, textr, lasti); if(lasti >= 0) break; while(!ptinrect(m->xy, textr) && (m->buttons & (1<<(but-1)))){ if(scrolling && ptinrect(m->xy, scrollr)){ noff = ((m->xy.y-scrollr.min.y)*nitem)/Dy(scrollr); noff -= nitemdrawn/2; if(noff < 0) noff = 0; if(noff > nitem-nitemdrawn) noff = nitem-nitemdrawn; if(noff != off){ off = noff; menupaint(menu, textr, off, nitemdrawn); menuscrollpaint(scrollr, off, nitem, nitemdrawn); } } *m = emouse(); } } bitblt(&screen, menur.min, b, menur, S); if(b != &screen) bfree(b); clipr(&screen, sc); if(lasti >= 0){ menu->lasthit = lasti+off; return cursorswitch(oldcursor), menu->lasthit; } cursorswitch(oldcursor); return -1; }