/* * nopoll * Provides handling for a dialogue box without polling (for error boxes * and so on * * v. 1.00 (30 July 1993) * * © 1993-1998 Straylight */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Steel library. * * Steel is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * Steel is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Steel. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*--------------------------------------------------------------------------- Support is provided for three action buttons, here referred to as 'OK', 'Cancel' and 'Other'. Fair enough? Good. 'OK' is the default action button, which may also be selected by pressing return. Pressing escape is equivalent to clicking Cancel. The 'Other' button (good, eh?) has no keyboard equivalent. To indicate that you don't want a particular button to exist, just pass -1 as the number. ---------------------------------------------------------------------------*/ #include "dbox.h" #include "wimpt.h" #include "coords.h" #include "bbc.h" #include "os.h" #include "nopoll.h" #include "interface.h" #include "sculptrix.h" #include "visdelay.h" #include "resspr.h" #include "swiv.h" #define OS_Mouse 0x2001C #define XWimpExt_Redraw 0x65783 static dbox nopoll__d; static dbox_field nopoll__f; /* * void nopoll__clickicon(dbox d,dbox_field f) * * Use * Clicks in a given field in a nice way */ static void nopoll__clickicon(dbox d,dbox_field f) { nopoll__d=d; nopoll__f=f; if (wimpt_options() & 7) dbox_clickicon(d,f); else dbox_selecticon(d,f,TRUE); } /* * void nopoll__unclick(void) * * Use * Unclicks a clicked icon */ static void nopoll__unclick(void) { if (wimpt_options() & 7) dbox_unclick(); else dbox_selecticon(nopoll__d,nopoll__f,FALSE); } /* * void nopoll__mouseRectangle(wimp_w window) * * Use * Sets up the mouse rectangle to the limits of the window specified. * * Parameters * wimp_w window == the window handle */ static void nopoll__mouseRectangle(wimp_w window) { wimp_wstate s; wimpt_noerr(wimp_get_wind_state(window,&s)); wimpt_noerr((os_error *)bbc_mouserect(s.o.box.x0-wimpt_dx(), s.o.box.y0-wimpt_dy(), s.o.box.x1, s.o.box.y1)); } /* * void nopoll__freeMouse(void) * * Use * Frees the mouse from the current mouse rectangle. */ static void nopoll__freeMouse(void) { bbc_mouserect(0,0,wimpt_scwidth()-wimpt_dx(),wimpt_scheight()-wimpt_dy()); } /* * void nopoll_showDbox(dbox d,nopoll_appearFlags flags) * * Use * Displays a dbox on-screen without polling the WIMP. Useful for * copyright windows and things. * * Parameters * dbox d == the dbox handle * nopoll_appearFlags flags == how you want the dbox to appear */ void nopoll_showDbox(dbox d,nopoll_appearFlags flags) { wimp_w wind=dbox_syshandle(d); wimp_redrawstr rdr; int more=0; switch (flags) { case nopoll_ASIS: dbox_display(d,dbox_STATIC_LASTPOS); break; case nopoll_CENTRE: dbox_display(d,dbox_STATIC_CENTRE); break; case nopoll_ONPTR: dbox_display(d,dbox_STATIC_OVERPTR); break; } rdr.w=wind; wimpt_noerr(wimp_redraw_wind(&rdr,&more)); while (more) { if (wimpt_options() & wimpt_OSCULPTRIX) { wimpt_noerr(sculptrix_setSpriteArea(resspr_area())); wimpt_noerr(sculptrix_redrawWindow(&rdr)); } if (wimpt_options() & wimpt_OINTERFACE) wimpt_noerr(interface_render3dWindow(&rdr)); if (wimpt_options() & wimpt_OWIMPEXT) wimpt_noerr(_swix(XWimpExt_Redraw,_in(1),&rdr)); if (!dbox_hasTitle(d)) dbox_drawEmbeddedTitle(&rdr,d); wimpt_noerr(wimp_get_rectangle(&rdr,&more)); } } /* * int nopoll_doDbox * ( * dbox d, * nopoll_appearFlags flags, * dbox_field OK, * dbox_field cancel, * dbox_field other * ) * * Use * Opens a NoPoll dialogue box, continues until it gets a sensible result, * closes it, and then returns the result. * * Parameters * dbox d == the dialogue box you want to use for this. * nopoll_appearFlags flags == how you want the box to appear (see above) * dbox_field OK == the number of the OK button * dbox_field cancel == the number of the Cancel button * dbox_field other == the number of the Other button * * Returns * One of the macros defined above, depending on what the user did. */ int nopoll_doDbox ( dbox d, nopoll_appearFlags flags, dbox_field OK, dbox_field cancel, dbox_field other ) { wimp_w wind=dbox_syshandle(d); wimp_wstate state; wimp_icon icn; wimp_box okBox={-1,-1,-1,-1}; wimp_box cancelBox=okBox; wimp_box otherBox=okBox; wimp_mousestr m; coords_cvtstr crds; int done=0; BOOL ignoreClick=TRUE; int b; coords_pointstr p; int key; int dummy; visdelay_state visstate=visdelay_suspend(); wimpt_noerr(wimp_get_point_info(&m)); nopoll_showDbox(d,flags); nopoll__mouseRectangle(wind); wimpt_noerr(wimp_get_wind_state(wind,&state)); crds.box=state.o.box; crds.scx=state.o.x; crds.scy=state.o.y; if (OK!=-1) { wimpt_noerr(wimp_get_icon_info(wind,OK,&icn)); okBox=icn.box; coords_box_toscreen(&okBox,&crds); } if (cancel!=-1) { wimpt_noerr(wimp_get_icon_info(wind,cancel,&icn)); cancelBox=icn.box; coords_box_toscreen(&cancelBox,&crds); } if (other!=-1) { wimpt_noerr(wimp_get_icon_info(wind,other,&icn)); otherBox=icn.box; coords_box_toscreen(&otherBox,&crds); } while (!done) { bbc_mouse(&p.x,&p.y,&b,0); if ((b==1 || b==4) && !ignoreClick) { if (coords_withinbox(&p,&okBox)) done=nopoll_OK; else if (coords_withinbox(&p,&cancelBox)) done=nopoll_CANCEL; else if (coords_withinbox(&p,&otherBox)) done=nopoll_OTHER; else ignoreClick=TRUE; } else { if (b!=1 && b!=4) ignoreClick=FALSE; key=0; dummy=0; wimpt_noerr(os_byte(129,&key,&dummy)); if (dummy!=0) key=-1; switch (key) { case 13: if (OK!=-1) done=nopoll_OK; break; case 27: if (cancel!=-1) done=nopoll_CANCEL; else if (OK!=-1) done=nopoll_OK; break; } } } visdelay_resume(visstate); switch (done) { case nopoll_OK: nopoll__clickicon(d,OK); break; case nopoll_CANCEL: nopoll__clickicon(d,cancel); break; case nopoll_OTHER: nopoll__clickicon(d,other); break; } dbox_hide(d); nopoll__unclick(); nopoll__freeMouse(); return (done); }