home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari FTP
/
ATARI_FTP_0693.zip
/
ATARI_FTP_0693
/
Mint
/
toswinsc.zoo
/
popup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-27
|
4KB
|
160 lines
/*
* Copyright 1992 Eric R. Smith. All rights reserved.
* Redistribution is permitted only if the distribution
* is not for profit, and only if all documentation
* (including, in particular, the file "copying")
* is included in the distribution in unmodified form.
* THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
* EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
* RISK.
*/
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <osbind.h>
#include "xgem.h"
/*
* pop up a menu at screen location (x, y), and deal with user
* interactions with it
*/
void
popup_menu( m, x, y )
MENU *m;
int x,y;
{
extern int entrylen __PROTO(( ENTRY * ));
extern char *entrystr __PROTO(( ENTRY *, int ));
OBJECT *popobj;
ENTRY *e;
int numobjects = 1;
int wide = 0;
int i;
int w, h;
int event, msx, msy, mbutton, mbreturn, keycode, dummy;
int curobj = -1;
int newobj;
int lowbyte;
msx = x; msy = y;
for (e = m->contents; e; e = e->next) {
numobjects++;
if ( (i = entrylen(e)) > wide)
wide = i;
}
popobj = malloc(numobjects * sizeof(OBJECT));
if (!popobj) return;
/* first, create the box around the menu */
popobj[0].ob_next = -1;
popobj[0].ob_head = 1;
popobj[0].ob_tail = numobjects - 1;
popobj[0].ob_type = G_BOX;
popobj[0].ob_flags = LASTOB; popobj[0].ob_state = NORMAL;
popobj[0].ob_spec = 0x00ff1100L;
popobj[0].ob_x = x/gl_wchar; popobj[0].ob_y = y/gl_hchar;
popobj[0].ob_width = wide;
popobj[0].ob_height = numobjects - 1;
i = 1;
for (e = m->contents; e; e = e->next) {
popobj[i].ob_next = (e->next) ? i+1 : 0;
popobj[i].ob_head = popobj[i].ob_tail = -1;
popobj[i].ob_type = G_STRING;
popobj[i].ob_flags = NONE;
popobj[i].ob_state = e->state;
popobj[i].ob_spec = (long)entrystr(e, wide);
if (!popobj[i].ob_spec) return;
popobj[i].ob_x = 0; popobj[i].ob_y = i - 1;
popobj[i].ob_width = wide; popobj[i].ob_height = 1;
i++;
}
popobj[i-1].ob_flags = LASTOB;
/* now, fix up the object tree */
for (i = 0; i < numobjects; i++)
rsrc_obfix(popobj, i);
/* find the rectangle the tree will appear in; make sure the whole menu
* will appear on-screen
*/
x = popobj[0].ob_x - 1; y = popobj[0].ob_y - 1;
w = popobj[0].ob_width + 2; h = popobj[0].ob_height + 2;
if (x + w > xdesk + wdesk) x = xdesk + wdesk - w;
if (y + h > ydesk + hdesk) y = ydesk + hdesk - h;
if (x < xdesk) x = xdesk;
if (y < ydesk) y = ydesk;
popobj[0].ob_x = x+1; popobj[0].ob_y = y+1;
/* display the tree */
wind_update(BEG_MCTRL);
form_dial(0, x, y, w, h, x, y, w, h);
objc_draw(popobj, 0, 1, x, y, w, h);
/* interact with it */
for(;;) {
event = evnt_multi(MU_BUTTON|MU_M1|MU_KEYBD,
2, 0x0001, 0x0001,
1, msx, msy, 1, 1,
0, 0, 0, 0, 0,
0L, 0L,
&msx, &msy, &mbutton, &dummy,
&keycode, &mbreturn);
if (event & MU_M1) {
if (msx >= x && msx <= x+w && msy >= y && msy <= y+h) {
newobj = objc_find(popobj, 0, 1, msx, msy);
} else newobj = -1;
if (curobj > 0 && curobj != newobj) {
objc_change(popobj, curobj, 0, x, y, w, h,
NORMAL, 1);
}
curobj = newobj;
if (curobj > 0 && popobj[curobj].ob_state != DISABLED) {
objc_change(popobj, curobj, 0,x,y,w,h,
SELECTED, 1);
} else {
curobj = -1;
}
}
if (event & MU_KEYBD) {
lowbyte = keycode & 0x00ff;
i = 1;
for (e = m->contents; e; e = e->next) {
if ((lowbyte && e->keycode == lowbyte) ||
e->keycode == keycode) {
curobj = i;
event |= MU_BUTTON;
break;
} else i++;
}
}
if (event & MU_BUTTON) {
break;
}
}
/* free memory allocated by `entrystr' */
for (i = 1; i < numobjects; i++)
free((void *)popobj[i].ob_spec);
free(popobj);
form_dial(3, x, y, w, h, x, y, w, h);
wind_update(END_MCTRL);
if (curobj > 0) {
for (e = m->contents; e; e = e->next) {
--curobj;
if (curobj == 0) {
(*e->func)(e->arg);
break;
}
}
}
}