Plan 9 from Bell Labs’s /sys/src/games/mandel/menuhit.c

Copyright © 2021 Plan 9 Foundation
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <libg.h>
#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.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);
	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);
	pt=Pt(menur.min.x+menur.max.x, menur.min.y+Margin);
	for(i=0; i<nitem; i++, pt.y+=font->height+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);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@plan9.bell-labs.com.