home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Club Elmshorn Atari PD
/
CCE_PD.iso
/
pc
/
0600
/
CCE_0678.ZIP
/
CCE_0678.PD
/
E_GEM135
/
SOURCE
/
POPUP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-17
|
9KB
|
428 lines
#include "proto.h"
static int ob_next(OBJECT *,int);
static void ob_change(OBJECT *,int,int);
static int ob_find(OBJECT *,int,int);
static int do_popup(OBJECT *,boolean,int,int *);
static int ob_next(OBJECT *tree,int start)
{
reg OBJECT *obj;
reg int i = start;
if (start<tree->ob_head)
start=tree->ob_head;
do
{
obj = tree + i;
if ((obj->ob_state & DISABLED)==0 && (obj->ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
return(i);
i = obj->ob_next;
}
while (i>=0);
return(FAIL);
}
static void ob_change(OBJECT *tree,int obj,int newstate)
{
reg OBJECT *ob = tree + obj;
int x,y;
objc_offset(tree,obj,&x,&y);
objc_change(tree,obj,0,x,y,ob->ob_width,ob->ob_height,newstate,1);
}
static int ob_find(OBJECT *tree,int x,int y)
{
reg int pos = objc_find(tree,ROOT,1,x,y);
if (pos>0 && ob_next(tree,pos)==pos)
return(pos);
else
return(FAIL);
}
static int do_popup(OBJECT *menu,boolean wrap,int last,int *dc)
{
reg int current,old = FAIL,ret = FAIL;
EVENT events =
{
MU_BUTTON | MU_M1 | MU_M2 | MU_KEYBD,
1,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,
{0,0,0,0,0,0,0,0}
};
_mouse_pos(&events.ev_mmox,&events.ev_mmoy);
if ((current = ob_find(menu,events.ev_mmox,events.ev_mmoy))<=0)
current = last;
for (;;)
{
reg int mpos;
if (current!=old)
{
if (old>0)
ob_change(menu,old,menu[old].ob_state & (~SELECTED));
if (current>0)
ob_change(menu,current,menu[current].ob_state | SELECTED);
old = current;
}
if ((mpos = objc_find(menu,ROOT,1,events.ev_mmox,events.ev_mmoy)) < 0)
{
events.ev_mm1flags = 0;
events.ev_mm1x = menu->ob_x;
events.ev_mm1y = menu->ob_y;
events.ev_mm1width = menu->ob_width;
events.ev_mm1height = menu->ob_height;
events.ev_mflags &= ~MU_M2;
}
else
{
events.ev_mm1flags = 1;
objc_offset(menu,mpos,&events.ev_mm1x,&events.ev_mm1y);
events.ev_mm1width = menu[mpos].ob_width;
events.ev_mm1height = menu[mpos].ob_height;
events.ev_mm2x = events.ev_mmox;
events.ev_mm2y = events.ev_mmoy;
events.ev_mflags |= MU_M2;
}
events.ev_mwich = Event_Multi(&events,0);
if (events.ev_mwich & MU_BUTTON)
{
if (!(events.ev_mmobutton & 1))
{
ret = ob_find(menu,events.ev_mmox,events.ev_mmoy);
break;
}
else
events.ev_mbstate = 0;
}
if (events.ev_mwich & (MU_M1|MU_M2))
{
current = ob_find(menu,events.ev_mmox,events.ev_mmoy);
if (events.ev_mwich & MU_M2)
{
events.ev_mm2x = events.ev_mmox;
events.ev_mm2y = events.ev_mmoy;
}
}
if (events.ev_mwich & MU_KEYBD)
{
int exitmode = FALSE;
switch (events.ev_mkreturn & 0x00ff)
{
case 13:
case 32:
ret = current;
exitmode = TRUE;
break;
case 27:
ret = FAIL;
exitmode = TRUE;
}
if (exitmode==FALSE)
{
switch (events.ev_mkreturn>>8)
{
case 97:
ret = FAIL;
exitmode = TRUE;
break;
case 71:
if (events.ev_mmokstate & 3)
{
reg int j;
for (j=menu->ob_head;j<=menu->ob_tail;j++)
if ((menu[j].ob_state & DISABLED)==0 && (menu[j].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
current = j;
}
else
current = ob_next(menu,menu->ob_head);
break;
case 75:
case 72:
{
reg int j,temp = FAIL;
if (current>menu->ob_head)
{
for (j=menu->ob_head;j<current;j++)
if ((menu[j].ob_state & DISABLED)==0 && (menu[j].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
temp = j;
}
if (temp<0 && (wrap || current<0))
{
for (j=menu->ob_head;j<=menu->ob_tail;j++)
if ((menu[j].ob_state & DISABLED)==0 && (menu[j].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
temp = j;
}
if (temp>0)
current = temp;
}
break;
case 77:
case 80:
if (current<menu->ob_tail)
{
if (current<0)
current = ob_next(menu,menu->ob_head);
else
{
int temp = ob_next(menu,menu[current].ob_next);
if (temp>0 && temp!=current)
current = temp;
else
current = ob_next(menu,menu->ob_head);
}
}
else if (wrap)
current = ob_next(menu,menu->ob_head);
break;
default:
{
int obj;
if ((obj=_is_hotkey(menu,events.ev_mkreturn,events.ev_mmokstate))>0)
{
if ((menu[obj].ob_state & DISABLED)==0 && (menu[obj].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
{
if (old>0)
ob_change(menu,old,menu[old].ob_state & (~SELECTED));
ob_change(menu,obj,menu[obj].ob_state | SELECTED);
evnt_timer(150,0);
exitmode = TRUE;
ret = obj;
}
}
}
}
}
if (exitmode)
break;
}
}
if (ret>0)
*dc = (events.ev_mbreturn>=2 || (events.ev_mmokstate & 3));
return (ret);
}
int Popup(POPUP *popup,int mode,int center,int x,int y,int *index,int select)
{
reg DIAINFO *info = popup->p_info;
reg OBJECT *menu = popup->p_menu,*tree = info->di_tree;
reg int current = FAIL,exit = FAIL,object;
int dc = FALSE;
graf_mouse(ARROW,NULL);
if (info)
{
object = (mode & POPUP_CYCLE) ? popup->p_cycle : popup->p_parent;
if (object>0)
ob_draw_chg(info,object,NULL,tree[object].ob_state|SELECTED,FALSE);
}
{
reg int i;
for (i=menu->ob_head;i<=menu->ob_tail;i++)
{
if (menu[i].ob_flags & SELECTABLE)
menu[i].ob_state &= ~SELECTED;
if (!(menu[i].ob_flags & HIDETREE))
{
if (i==select)
{
if (mode & POPUP_CHECK)
menu[i].ob_state |= CHECKED;
if (current>=0)
menu[current].ob_state &= ~CHECKED;
current=i;
}
else if (menu[i].ob_state & CHECKED)
{
if (!(mode & POPUP_CHECK) || current>=0)
menu[i].ob_state &= ~CHECKED;
else
current = i;
}
}
}
}
if (!(mode & POPUP_CYCLE))
{
int sx,sy,sw = menu->ob_width>>1,sh = menu->ob_height>>1,dummy;
long mem = 0l;
MFDB dial;
_mouse_pos(&sx,&sy);
if (info && popup->p_button>0)
{
int bx,by;
objc_offset(tree,popup->p_button,&bx,&by);
if (x<=0)
x = bx;
if (y<=0)
y = by;
}
switch (center)
{
case CENTER:
{
INFOVSCR *vscr;
form_center(menu,&dummy,&dummy,&dummy,&dummy);
if (get_cookie(COOKIE_VSCR,(long *) &vscr) && (vscr->cookie==COOKIE_XBRA))
{
menu->ob_x = vscr->x + (vscr->w>>1) - sw;
menu->ob_y = vscr->y + (vscr->h>>1) - sh;
}
}
break;
case XYPOS:
menu->ob_x = x;
menu->ob_y = y;
break;
case MOUSEPOS:
menu->ob_x = sx - sw;
menu->ob_y = sy - sh;
break;
case XPOS:
menu->ob_x = x;
menu->ob_y = sy - sh;
break;
case YPOS:
menu->ob_x = sx - sw;
menu->ob_y = y;
break;
case OBJPOS:
menu->ob_x = x;
menu->ob_y = y;
if (current>=0)
{
menu->ob_x -= menu[current].ob_x;
menu->ob_y -= menu[current].ob_y;
}
}
Min(&menu->ob_x,clip.v_x2 - menu->ob_width - 3);
Max(&menu->ob_x,clip.v_x1 + 3);
Min(&menu->ob_y,clip.v_y2 - menu->ob_height - 3);
Max(&menu->ob_y,clip.v_y1 + 3);
sx = menu->ob_x - 3;
sy = menu->ob_y - 3;
sw = menu->ob_width + 6;
sh = menu->ob_height + 6;
_beg_ctrl();
mfdb(&dial,NULL,sw,sh,0,planes);
{
reg long len = mfdb_size(&dial);
if ((long) Malloc(-1l)>(len+4096l))
{
if ((mem = (long) Malloc(len+256l))>0l)
{
dial.fd_addr = (int *) ((mem & 0xfffffffel) + 2);
_bitblt(menu,&dial,TRUE);
goto draw_popup;
}
}
}
form_dial(FMD_START,sx,sy,sw,sh,sx,sy,sw,sh);
draw_popup:
objc_draw(menu,ROOT,MAX_DEPTH,sx,sy,sw,sh);
exit = do_popup(menu,popup->p_wrap,current,&dc);
if (mem)
{
_bitblt(menu,&dial,FALSE);
Mfree((void *) mem);
}
else
form_dial(FMD_FINISH,sx,sy,sw,sh,sx,sy,sw,sh);
_end_ctrl();
}
else
{
if (current<0 || current>=menu->ob_tail)
exit = ob_next(menu,menu->ob_head);
else
{
int temp = ob_next(menu,menu[current].ob_next);
exit = (temp>0) ? temp : ob_next(menu,menu->ob_head);
}
evnt_timer(50,0);
}
if (info && object>0)
ob_draw_chg(info,object,NULL,tree[object].ob_state & (~SELECTED),FALSE);
if (exit>0)
{
if (mode & POPUP_CHECK)
{
if (current>=0)
menu[current].ob_state &= ~CHECKED;
menu[exit].ob_state |= CHECKED;
}
if (info && popup->p_set && popup->p_button>0)
{
ob_set_text(tree,popup->p_button,ob_get_text(menu,exit,0));
ob_draw_chg(info,popup->p_button,NULL,FAIL,FALSE);
if (popup->p_cycle>0)
ob_draw_chg(info,popup->p_cycle,NULL,FAIL,FALSE);
}
if (index)
{
reg int i = 1,radio = 0;
do
{
if ((menu[i].ob_flags & (SELECTABLE|HIDETREE))==SELECTABLE)
{
if (i==exit)
{
*index = radio;
break;
}
radio++;
}
i = menu[i].ob_next;
} while (i>=0);
}
}
if (exit<=0)
return(0);
else
return ((dc) ? (exit|0x8000) : exit);
}