This is a patch to update saved/piemenus and adds the manpages to the saved patch again, as they seem to be lost at the last update. Reference: /n/sources/patch/sorry/rio-piemenus-smallmenu Date: Fri Sep 23 02:37:26 CES 2005 --- /sys/src/libdraw/epiemenuhit.c Thu Jan 1 00:00:00 1970 +++ /sys/src/libdraw/epiemenuhit.c Fri Sep 23 02:34:59 2005 @@ -0,0 +1,209 @@ +#include +#include +#include +#include + +static Image *back, *bord, *high; + +double +erad(double i) +{ + + return (i * PI) / 180; +} + +double +edist(Point p0, Point p1) +{ + + return sqrt((p0.x - p1.x) * (p0.x - p1.x) + (p0.y - p1.y) * (p0.y - p1.y)); +} + +Point +ecente(Point p0, Point p1, Point p2) +{ + double l, d; + Point r0, r1; + + l = edist(p2, p0); + r0.x = p2.x + (((p0.x - p2.x) / l) * l / 2); + r0.y = p2.y + (((p0.y - p2.y) / l) * l / 2); + + l = edist(p1, p0); + r1.x = p1.x + (((p0.x - p1.x) / l) * l / 2); + r1.y = p1.y + (((p0.y - p1.x) / l) * l / 2); + + l = p2.x - r1.x - p1.x + r0.x; + d = (double)(r0.x - r1.x) / l; + + r1.x = r0.x + d * (p1.x - r0.x); + r1.y = r0.y + d * (p1.y - r0.y); + + return r1; +} + +void +edraw_pie(Point p, int r, Image *b, Image *w, Image *h, Menu *m, int a, int n) +{ + Point p0, p1; + double d, e, sr; + char *item; + + e = 360 / n; + d = 0; + sr = -1; + + ellipse(screen, p, r, r, 1, h, ZP); + fillellipse(screen, p, r - 1, r - 1, w, ZP); + if(a > 0) + fillarc(screen, p, r, r, b, ZP, (a - 1) * e, e); + + p0 = p; + p1 = p; + + p0.x += cos(erad(d)) * r; + p0.y += sin(erad(d)) * r; + p1.x += cos(erad(d + e)) * r; + p1.y += sin(erad(d + e)) * r; + + if(n > 1) + sr = edist(ecente(p, p0, p1), p); + else + sr = 0; + + d = e / 2; + + while(--n >= 0){ + p0 = p; + item = strdup(m->item[n]); + if(strlen(item) > 8){ + item[8] = '\0'; + item[7] = '.'; + item[6] = '.'; + item[5] = '.'; + } + + p0.x += cos(erad(d)) * sr; + p0.y += sin(erad(d)) * sr; + + p0.x -= stringwidth(font, item) / 2; + p0.y -= font->height / 2; + + string(screen, p0, (n == (a - 1)) ? display->white : display->black, ZP, font, item); + free(item); + d += e; + } + + return; +} + +int +epiemenuhit(int but, Mouse *m, Menu *menu) +{ + Rectangle menur; + Image *b, *back, *high, *bord; + int maxwid, nitem, i, t; + double cdeli, cpart, radius; + Point p; + char *item, set; + + back = allocimagemix(display, DPalegreen, DWhite); + high = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkgreen); + bord = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedgreen); + set = 1; + + if(back == nil || high == nil || bord == nil){ + set = 0; + back = display->white; + high = display->black; + bord = display->black; + } + + replclipr(screen, 0, screen->r); + maxwid = 0; + nitem = 0; + while(item = menu->item ? menu->item[nitem] : (*menu->gen)(nitem)){ + item = strdup(item); + if(strlen(item) > 8) + item[8] = '\0'; + + i = stringwidth(font, item); + if(i > maxwid) + maxwid = i; + free(item); + nitem++; + } + if(menu->lasthit < 0 || menu->lasthit >= nitem) + menu->lasthit = -1; + + p = m->xy; + radius = ((font->height / 2) + maxwid); + radius += radius * nitem / 8; + if(p.x + radius > screen->r.max.x) + p.x = screen->r.max.x - radius; + if(p.x - radius < screen->r.min.x) + p.x = screen->r.min.x + radius; + if(p.y + radius > screen->r.max.y) + p.y = screen->r.max.y - radius; + if(p.y - radius < screen->r.min.y) + p.y = screen->r.min.y + radius; + emoveto(p); + + menur.min = Pt(p.x - radius - 1, p.y - radius - 1); + menur.max = Pt(p.x + radius + 2, p.y + radius + 2); + + cpart = 360 / nitem; + cdeli = cpart / 2; + + b = allocimage(display, Rect(0, 0, Dx(menur), Dy(menur)), screen->chan, 0, DNofill); + if(b == 0) + b = screen; + draw(b, b->r, screen, nil, menur.min); + + edraw_pie(p, radius, high, back, bord, menu, menu->lasthit, nitem); + + while(m->buttons & (1<<(but-1))){ + if(edist(p, m->xy) < radius && edist(p, m->xy) != 0){ + cdeli = acos((p.x - m->xy.x) / edist(p, m->xy)); + if(m->xy.y >= p.y) + cdeli += erad(180); + if(m->xy.y < p.y) + cdeli = erad(180) - cdeli; + + i = -1; + t = -1; + while(++t <= nitem){ + if(cdeli < erad(t * cpart) && cdeli <= erad((t + 1) * cpart)){ + i = t; + break; + } + } + + if(i != menu->lasthit || (menu->lasthit == -1 && i != -1)){ + menu->lasthit = i; + edraw_pie(p, radius, high, back, bord, menu, menu->lasthit, nitem); + } + } else { + if(menu->lasthit != -1){ + menu->lasthit = -1; + edraw_pie(p, radius, high, back, bord, menu, menu->lasthit, nitem); + } + } + flushimage(display, 1); + *m = emouse(); + } + + draw(screen, menur, b, nil, ZP); + if(b != screen) + freeimage(b); + + replclipr(screen, 0, screen->clipr); + + if(set){ + freeimage(back); + freeimage(bord); + freeimage(high); + } + + return menu->lasthit - 1; +} --- /sys/src/libdraw/piemenuhit.c Thu Jan 1 00:00:00 1970 +++ /sys/src/libdraw/piemenuhit.c Fri Sep 23 02:35:12 2005 @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include + +static Image *back, *bord, *high; + +double +rad(double i) +{ + + return (i * PI) / 180; +} + +double +dist(Point p0, Point p1) +{ + + return sqrt((p0.x - p1.x) * (p0.x - p1.x) + (p0.y - p1.y) * (p0.y - p1.y)); +} + +Point +cente(Point p0, Point p1, Point p2) +{ + double l, d; + Point r0, r1; + + l = dist(p2, p0); + r0.x = p2.x + (((p0.x - p2.x) / l) * l / 2); + r0.y = p2.y + (((p0.y - p2.y) / l) * l / 2); + + l = dist(p1, p0); + r1.x = p1.x + (((p0.x - p1.x) / l) * l / 2); + r1.y = p1.y + (((p0.y - p1.y) / l) * l / 2); + + l = p2.y - r1.y - p1.y + r0.y; + d = (double)(r0.y - r1.y) / l; + + r1.x = r0.x + d * (p1.x - r0.x); + r1.y = r0.y + d * (p1.y - r0.y); + + return r1; +} + +void +draw_pie(Point p, int r, Image *b, Image *w, Image *h, Menu *m, int a, int n) +{ + Point p0, p1; + double d, e, sr; + char *item; + + e = 360 / n; + d = 0; + sr = -1; + + ellipse(screen, p, r, r, 1, h, ZP); + fillellipse(screen, p, r - 1, r - 1, w, ZP); + if(a > 0) + fillarc(screen, p, r, r, b, ZP, (a - 1) * e, e); + + p0 = p; + p1 = p; + + p0.x += cos(rad(d)) * r; + p0.y += sin(rad(d)) * r; + p1.x += cos(rad(d + e)) * r; + p1.y += sin(rad(d + e)) * r; + + if(n > 1) + sr = dist(cente(p, p0, p1), p); + else + sr = 0; + + d = e / 2; + + while(--n >= 0){ + p0 = p; + item = strdup(m->item[n]); + if(strlen(item) > 8){ + item[8] = '\0'; + item[7] = '.'; + item[6] = '.'; + item[5] = '.'; + } + + p0.x += cos(rad(d)) * sr; + p0.y += sin(rad(d)) * sr; + + p0.x -= stringwidth(font, item) / 2; + p0.y -= font->height / 2; + + string(screen, p0, (n == (a - 1)) ? display->white : display->black, ZP, font, item); + free(item); + d += e; + } + + return; +} + +int +piemenuhit(int but, Mousectl *mc, Menu *menu, Screen *scr) +{ + Rectangle menur; + Image *b, *backup, *back, *high, *bord; + int maxwid, nitem, i, t, set; + double cdeli, cpart, radius; + Point p; + char *item; + + back = allocimagemix(display, DPalegreen, DWhite); + high = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkgreen); + bord = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DMedgreen); + set = 1; + + if(back == nil || high == nil || bord == nil){ + set = 0; + back = display->white; + high = display->black; + bord = display->black; + } + + replclipr(screen, 0, screen->r); + maxwid = 0; + nitem = 0; + while(item = menu->item ? menu->item[nitem] : (*menu->gen)(nitem)){ + item = strdup(item); + if(strlen(item) > 8) + item[8] = '\0'; + + i = stringwidth(font, item); + if(i > maxwid) + maxwid = i; + free(item); + nitem++; + } + if(menu->lasthit < 0 || menu->lasthit >= nitem) + menu->lasthit = -1; + + p = mc->xy; + radius = ((font->height / 2) + maxwid); + radius += radius * nitem / 8; + if(p.x + radius > screen->r.max.x) + p.x = screen->r.max.x - radius; + if(p.x - radius < screen->r.min.x) + p.x = screen->r.min.x + radius; + if(p.y + radius > screen->r.max.y) + p.y = screen->r.max.y - radius; + if(p.y - radius < screen->r.min.y) + p.y = screen->r.min.y + radius; + moveto(mc, p); + + menur.min = Pt(p.x - radius - 1, p.y - radius - 1); + menur.max = Pt(p.x + radius + 2, p.y + radius + 2); + + cpart = 360 / nitem; + cdeli = cpart / 2; + + if(scr){ + b = allocwindow(scr, menur, Refbackup, DNofill); + if(b == nil) + b = screen; + backup = nil; + }else{ + b = screen; + backup = allocimage(display, Rect(0, 0, Dx(menur), Dy(menur)), screen->chan, 0, DNofill); + if(backup) + draw(backup, backup->r, screen, nil, menur.min); + } + + draw_pie(p, radius, high, back, bord, menu, menu->lasthit, nitem); + + while(mc->buttons & (1<<(but-1))){ + if(dist(p, mc->xy) < radius && dist(p, mc->xy) != 0){ + cdeli = acos((p.x - mc->xy.x) / dist(p, mc->xy)); + if(mc->xy.y >= p.y) + cdeli += rad(180); + if(mc->xy.y < p.y) + cdeli = rad(180) - cdeli; + + i = -1; + t = -1; + while(++t <= nitem){ + if(cdeli < rad(t * cpart) && cdeli <= rad((t + 1) * cpart)){ + i = t; + break; + } + } + + if(i != menu->lasthit || (menu->lasthit == -1 && i != -1)){ + menu->lasthit = i; + draw_pie(p, radius, high, back, bord, menu, menu->lasthit, nitem); + } + } else { + if(menu->lasthit != -1){ + menu->lasthit = -1; + draw_pie(p, radius, high, back, bord, menu, menu->lasthit, nitem); + } + } + readmouse(mc); + } + if(b != screen) + freeimage(b); + if(backup){ + draw(screen, menur, backup, nil, ZP); + freeimage(backup); + } + replclipr(screen, 0, screen->clipr); + flushimage(display, 1); + + if(set){ + freeimage(back); + freeimage(bord); + freeimage(high); + } + + return menu->lasthit - 1; +} --- /sys/src/libdraw/mkfile Fri Sep 23 02:35:31 2005 +++ /sys/src/libdraw/mkfile Fri Sep 23 02:35:27 2005 @@ -21,6 +21,7 @@ egetrect.$O\ ellipse.$O\ emenuhit.$O\ + epiemenuhit.$O\ event.$O\ fmt.$O\ font.$O\ @@ -38,6 +39,7 @@ mouse.$O\ newwindow.$O\ openfont.$O\ + piemenuhit.$O\ poly.$O\ loadimage.$O\ readcolmap.$O\ --- /sys/man/2/INDEX Fri Sep 23 02:35:57 2005 +++ /sys/man/2/INDEX Fri Sep 23 02:35:51 2005 @@ -417,6 +417,7 @@ einit event ekbd event emenuhit event +epiemenuhit event emouse event emoveto event eread event @@ -868,6 +869,7 @@ getrect mouse initmouse mouse menuhit mouse +piemenuhit mouse mouse mouse moveto mouse readmouse mouse --- /sys/man/2/event Fri Sep 23 02:36:24 2005 +++ /sys/man/2/event Fri Sep 23 02:36:20 2005 @@ -1,6 +1,6 @@ .TH EVENT 2 .SH NAME -event, einit, estart, estartfn, etimer, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, ereadmouse, eatomouse, eresized, egetrect, edrawgetrect, emenuhit, emoveto, esetcursor, Event, Mouse, Menu \- graphics events +event, einit, estart, estartfn, etimer, eread, emouse, ekbd, ecanread, ecanmouse, ecankbd, ereadmouse, eatomouse, eresized, egetrect, edrawgetrect, emenuhit, epiemenuhit, emoveto, esetcursor, Event, Mouse, Menu \- graphics events .SH SYNOPSIS .nf .PP @@ -69,6 +69,8 @@ .B int emenuhit(int but, Mouse *m, Menu *menu) .PP +.B +int epiemenuhit(int but, Mouse *m, Menu *menu) .PP .B int emoveto(Point p) @@ -359,6 +361,12 @@ The .I m argument is filled in with the final mouse event. +.PP +.I Epiemenuhit +is the same like +.I emenuhit +, but draws instead a piemenu, where menuitems longer then eight characters +are shortened. .PP .I Emoveto moves the mouse cursor to the position --- /sys/man/2/mouse Fri Sep 23 02:36:55 2005 +++ /sys/man/2/mouse Fri Sep 23 02:36:51 2005 @@ -1,6 +1,6 @@ .TH MOUSE 2 .SH NAME -initmouse, readmouse, closemouse, moveto, cursorswitch, getrect, drawgetrect, menuhit, setcursor \- mouse control +initmouse, readmouse, closemouse, moveto, cursorswitch, getrect, drawgetrect, menuhit, setcursor, piemenuhit \- mouse control .SH SYNOPSIS .nf .B @@ -42,6 +42,9 @@ .PP .B int menuhit(int but, Mousectl *mc, Menu *menu, Screen *scr) +.PP +.B +int piemenuhit(int but, Mousectl *mc, Menu *menu, Screen *scr) .fi .SH DESCRIPTION These functions access and control a mouse in a multi-threaded environment. @@ -238,6 +241,16 @@ .IR emenuhit , creating backing store for the menu, writing the menu directly on the display, and restoring the display when the menu is removed. +.PP +.IR Piemenuhit +is a replacement function of +.I menuhit +, has the brother function +.I epiemenuhit +, that is a replacement for +.I emenuhit +and draws instead of a rectangle menu piemenus. If the +name of a menuitem is longer then eight characters, it is shortened. .PP .SH SOURCE .B /sys/src/libdraw