Initial revision
[ssr] / StraySrc / Libraries / Steel / c / nopoll
1 /*
2 * nopoll
3 * Provides handling for a dialogue box without polling (for error boxes
4 * and so on
5 *
6 * v. 1.00 (30 July 1993)
7 *
8 * © 1993-1998 Straylight
9 */
10
11 /*----- Licensing note ----------------------------------------------------*
12 *
13 * This file is part of Straylight's Steel library.
14 *
15 * Steel is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * Steel is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with Steel. If not, write to the Free Software Foundation,
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 */
29
30 /*---------------------------------------------------------------------------
31
32 Support is provided for three action buttons, here referred to as 'OK',
33 'Cancel' and 'Other'. Fair enough? Good. 'OK' is the default action
34 button, which may also be selected by pressing return. Pressing escape
35 is equivalent to clicking Cancel. The 'Other' button (good, eh?) has no
36 keyboard equivalent. To indicate that you don't want a particular button
37 to exist, just pass -1 as the number.
38
39 ---------------------------------------------------------------------------*/
40
41 #include "dbox.h"
42 #include "wimpt.h"
43 #include "coords.h"
44 #include "bbc.h"
45 #include "os.h"
46 #include "nopoll.h"
47 #include "interface.h"
48 #include "sculptrix.h"
49 #include "visdelay.h"
50 #include "resspr.h"
51 #include "swiv.h"
52
53 #define OS_Mouse 0x2001C
54 #define XWimpExt_Redraw 0x65783
55
56 static dbox nopoll__d;
57 static dbox_field nopoll__f;
58
59 /*
60 * void nopoll__clickicon(dbox d,dbox_field f)
61 *
62 * Use
63 * Clicks in a given field in a nice way
64 */
65
66 static void nopoll__clickicon(dbox d,dbox_field f)
67 {
68 nopoll__d=d;
69 nopoll__f=f;
70 if (wimpt_options() & 7)
71 dbox_clickicon(d,f);
72 else
73 dbox_selecticon(d,f,TRUE);
74 }
75
76 /*
77 * void nopoll__unclick(void)
78 *
79 * Use
80 * Unclicks a clicked icon
81 */
82
83 static void nopoll__unclick(void)
84 {
85 if (wimpt_options() & 7)
86 dbox_unclick();
87 else
88 dbox_selecticon(nopoll__d,nopoll__f,FALSE);
89 }
90
91 /*
92 * void nopoll__mouseRectangle(wimp_w window)
93 *
94 * Use
95 * Sets up the mouse rectangle to the limits of the window specified.
96 *
97 * Parameters
98 * wimp_w window == the window handle
99 */
100
101 static void nopoll__mouseRectangle(wimp_w window)
102 {
103 wimp_wstate s;
104 wimpt_noerr(wimp_get_wind_state(window,&s));
105 wimpt_noerr((os_error *)bbc_mouserect(s.o.box.x0-wimpt_dx(),
106 s.o.box.y0-wimpt_dy(),
107 s.o.box.x1,
108 s.o.box.y1));
109 }
110
111 /*
112 * void nopoll__freeMouse(void)
113 *
114 * Use
115 * Frees the mouse from the current mouse rectangle.
116 */
117
118 static void nopoll__freeMouse(void)
119 {
120 bbc_mouserect(0,0,wimpt_scwidth()-wimpt_dx(),wimpt_scheight()-wimpt_dy());
121 }
122
123 /*
124 * void nopoll_showDbox(dbox d,nopoll_appearFlags flags)
125 *
126 * Use
127 * Displays a dbox on-screen without polling the WIMP. Useful for
128 * copyright windows and things.
129 *
130 * Parameters
131 * dbox d == the dbox handle
132 * nopoll_appearFlags flags == how you want the dbox to appear
133 */
134
135 void nopoll_showDbox(dbox d,nopoll_appearFlags flags)
136 {
137 wimp_w wind=dbox_syshandle(d);
138 wimp_redrawstr rdr;
139 int more=0;
140
141 switch (flags)
142 {
143 case nopoll_ASIS:
144 dbox_display(d,dbox_STATIC_LASTPOS);
145 break;
146 case nopoll_CENTRE:
147 dbox_display(d,dbox_STATIC_CENTRE);
148 break;
149 case nopoll_ONPTR:
150 dbox_display(d,dbox_STATIC_OVERPTR);
151 break;
152 }
153 rdr.w=wind;
154 wimpt_noerr(wimp_redraw_wind(&rdr,&more));
155 while (more)
156 {
157 if (wimpt_options() & wimpt_OSCULPTRIX)
158 {
159 wimpt_noerr(sculptrix_setSpriteArea(resspr_area()));
160 wimpt_noerr(sculptrix_redrawWindow(&rdr));
161 }
162 if (wimpt_options() & wimpt_OINTERFACE)
163 wimpt_noerr(interface_render3dWindow(&rdr));
164 if (wimpt_options() & wimpt_OWIMPEXT)
165 wimpt_noerr(_swix(XWimpExt_Redraw,_in(1),&rdr));
166 if (!dbox_hasTitle(d))
167 dbox_drawEmbeddedTitle(&rdr,d);
168 wimpt_noerr(wimp_get_rectangle(&rdr,&more));
169 }
170 }
171
172 /*
173 * int nopoll_doDbox
174 * (
175 * dbox d,
176 * nopoll_appearFlags flags,
177 * dbox_field OK,
178 * dbox_field cancel,
179 * dbox_field other
180 * )
181 *
182 * Use
183 * Opens a NoPoll dialogue box, continues until it gets a sensible result,
184 * closes it, and then returns the result.
185 *
186 * Parameters
187 * dbox d == the dialogue box you want to use for this.
188 * nopoll_appearFlags flags == how you want the box to appear (see above)
189 * dbox_field OK == the number of the OK button
190 * dbox_field cancel == the number of the Cancel button
191 * dbox_field other == the number of the Other button
192 *
193 * Returns
194 * One of the macros defined above, depending on what the user did.
195 */
196
197 int nopoll_doDbox
198 (
199 dbox d,
200 nopoll_appearFlags flags,
201 dbox_field OK,
202 dbox_field cancel,
203 dbox_field other
204 )
205 {
206 wimp_w wind=dbox_syshandle(d);
207 wimp_wstate state;
208 wimp_icon icn;
209 wimp_box okBox={-1,-1,-1,-1};
210 wimp_box cancelBox=okBox;
211 wimp_box otherBox=okBox;
212 wimp_mousestr m;
213 coords_cvtstr crds;
214 int done=0;
215 BOOL ignoreClick=TRUE;
216 int b;
217 coords_pointstr p;
218 int key;
219 int dummy;
220 visdelay_state visstate=visdelay_suspend();
221 wimpt_noerr(wimp_get_point_info(&m));
222 nopoll_showDbox(d,flags);
223 nopoll__mouseRectangle(wind);
224 wimpt_noerr(wimp_get_wind_state(wind,&state));
225 crds.box=state.o.box;
226 crds.scx=state.o.x;
227 crds.scy=state.o.y;
228 if (OK!=-1)
229 {
230 wimpt_noerr(wimp_get_icon_info(wind,OK,&icn));
231 okBox=icn.box;
232 coords_box_toscreen(&okBox,&crds);
233 }
234 if (cancel!=-1)
235 {
236 wimpt_noerr(wimp_get_icon_info(wind,cancel,&icn));
237 cancelBox=icn.box;
238 coords_box_toscreen(&cancelBox,&crds);
239 }
240 if (other!=-1)
241 {
242 wimpt_noerr(wimp_get_icon_info(wind,other,&icn));
243 otherBox=icn.box;
244 coords_box_toscreen(&otherBox,&crds);
245 }
246 while (!done)
247 {
248 bbc_mouse(&p.x,&p.y,&b,0);
249 if ((b==1 || b==4) && !ignoreClick)
250 {
251 if (coords_withinbox(&p,&okBox))
252 done=nopoll_OK;
253 else if (coords_withinbox(&p,&cancelBox))
254 done=nopoll_CANCEL;
255 else if (coords_withinbox(&p,&otherBox))
256 done=nopoll_OTHER;
257 else
258 ignoreClick=TRUE;
259 }
260 else
261 {
262 if (b!=1 && b!=4)
263 ignoreClick=FALSE;
264 key=0;
265 dummy=0;
266 wimpt_noerr(os_byte(129,&key,&dummy));
267 if (dummy!=0)
268 key=-1;
269 switch (key)
270 {
271 case 13:
272 if (OK!=-1)
273 done=nopoll_OK;
274 break;
275 case 27:
276 if (cancel!=-1)
277 done=nopoll_CANCEL;
278 else if (OK!=-1)
279 done=nopoll_OK;
280 break;
281 }
282 }
283 }
284 visdelay_resume(visstate);
285 switch (done)
286 {
287 case nopoll_OK:
288 nopoll__clickicon(d,OK);
289 break;
290 case nopoll_CANCEL:
291 nopoll__clickicon(d,cancel);
292 break;
293 case nopoll_OTHER:
294 nopoll__clickicon(d,other);
295 break;
296 }
297 dbox_hide(d);
298 nopoll__unclick();
299 nopoll__freeMouse();
300 return (done);
301 }