Updated to latest source.
[AROS-Contrib.git] / bgui / request.c
blob8cbe7a76c57717924398c52c9b203f6bd4b80171
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * request.c
7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
13 * $Log$
14 * Revision 42.5 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.4 2003/01/18 19:10:00 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.3 2000/08/09 11:45:57 chodorowski
21 * Removed a lot of #ifdefs that disabled the AROS_LIB* macros when not building on AROS. This is now handled in contrib/bgui/include/bgui_compilerspecific.h.
23 * Revision 42.2 2000/05/15 19:27:02 stegerg
24 * another hundreds of REG() macro replacements in func headers/protos.
26 * Revision 42.1 2000/05/14 23:32:48 stegerg
27 * changed over 200 function headers which all use register
28 * parameters (oh boy ...), because the simple REG() macro
29 * doesn't work with AROS. And there are still hundreds
30 * of headers left to be fixed :(
32 * Many of these functions would also work with stack
33 * params, but since i have fixed every single one
34 * I encountered up to now, I guess will have to do
35 * the same for the rest.
37 * Revision 42.0 2000/05/09 22:10:03 mlemos
38 * Bumped to revision 42.0 before handing BGUI to AROS team
40 * Revision 41.11 2000/05/09 19:54:59 mlemos
41 * Merged with the branch Manuel_Lemos_fixes.
43 * Revision 41.10 1998/02/25 21:12:59 mlemos
44 * Bumping to 41.10
46 * Revision 1.1 1998/02/25 17:09:37 mlemos
47 * Ian sources
52 #include "include/classdefs.h"
55 * IDCMPHook data.
57 typedef struct {
58 struct bguiRequest *ihd_Request; /* Requester structure. */
59 Object *ihd_ReturnObj; /* Return key object. */
60 ULONG ihd_MaxID; /* Maximum gadget ID. */
61 } IHD;
64 * Parse a button label.
66 //STATIC ASM UBYTE *GetButtonName( REG(a0) UBYTE *source, REG(a1) UBYTE *uc, REG(d0) ULONG uchar )
67 STATIC ASM REGFUNC3(UBYTE *, GetButtonName,
68 REGPARAM(A0, UBYTE *, source),
69 REGPARAM(A1, UBYTE *, uc),
70 REGPARAM(D0, ULONG, uchar))
72 uc[0] = uc[1] = 0;
75 * Search for the end-of-string or
76 * the seperator character.
78 while (*source && *source != '|')
81 * Look up the character
82 * to underline.
84 if (*source == uchar)
86 uc[0] = tolower(source[1]);
88 source++;
92 * When we reached a seperator we
93 * truncate the gadget string and
94 * return a pointer to the next
95 * name.
97 if (*source == '|')
99 *source++ = 0;
100 return source;
104 * The end, finito, ende, einde....
106 return NULL;
108 REGFUNC_END
111 * Create the button group.
113 STATIC Object *CreateButtonGroup( UBYTE *gstring, ULONG xen, UBYTE uchar, ULONG *maxid, Object **retobj )
115 Object *master, *button;
116 UBYTE *ptr, underscore[ 2 ];
117 UWORD id = 2, style = FS_NORMAL;
118 BOOL sing = FALSE, got_def = FALSE;
121 * Single gadget?
123 if (!strchr( gstring, '|'))
124 sing = TRUE;
127 * Create a horizontal master group.
129 if (master = BGUI_NewObject(BGUI_GROUP_GADGET, GROUP_Spacing, GRSPACE_WIDE, GROUP_EqualWidth, TRUE, TAG_END))
132 * Add a spacing object for single
133 * gadget requesters.
135 if (sing)
137 if (!AsmDoMethod(master, GRM_ADDSPACEMEMBER, DEFAULT_WEIGHT))
138 goto fail;
142 * Loop to get all the gadgets
143 * names.
145 while (ptr = gstring)
148 * Get a pointer to the next
149 * gadget name.
151 gstring = GetButtonName( gstring, &underscore[ 0 ], uchar );
154 * Default button?
156 if ((*ptr == '*') && (!got_def))
158 ptr++;
159 got_def = TRUE;
160 style = FSF_BOLD;
164 * Create the button.
166 if (button = BGUI_NewObject(BGUI_BUTTON_GADGET, LAB_Label, ptr, LAB_Style, style, LAB_Underscore, uchar,
167 GA_ID, id++, BT_Key, underscore, xen ? FRM_Type : TAG_IGNORE, FRTYPE_XEN_BUTTON, TAG_DONE))
170 * Pick this button if it's the first
171 * created or the default button.
173 if ((id == 3) || (style == FSF_BOLD))
174 *retobj = button;
177 * Add it to the master group.
179 if ( ! AsmDoMethod( master, GRM_ADDMEMBER, button, LGO_FixMinHeight, TRUE, TAG_END ))
180 goto fail;
183 else
186 * Button creation failed.
188 fail:
189 DisposeObject( master );
190 return NULL;
193 * Reset style.
195 style = FS_NORMAL;
199 * Save the maximum gadget ID.
201 *maxid = id - 2;
204 * Add a spacing object for single
205 * gadget requesters.
207 if (sing)
209 if (!AsmDoMethod(master, GRM_ADDSPACEMEMBER, DEFAULT_WEIGHT))
210 goto fail;
214 * The last (right most) button get's
215 * 0 as it's ID to keep compatible with
216 * intuition's EasyRequest().
218 DoSetMethod(button, NULL, GA_ID, 1, TAG_END);
221 * Return the master group.
223 return master;
225 return NULL;
229 * Requester IDCMP hook.
231 //STATIC SAVEDS ASM VOID ReqHookFunc(REG(a0) struct Hook *hook, REG(a2) Object *window, REG(a1) struct IntuiMessage *msg)
232 STATIC SAVEDS ASM REGFUNC3(VOID, ReqHookFunc,
233 REGPARAM(A0, struct Hook *, hook),
234 REGPARAM(A2, Object *, window),
235 REGPARAM(A1, struct IntuiMessage *, msg))
237 IHD *ihd = (IHD *)hook->h_Data;
238 int id = 0;
241 * Which key was pressed?
243 switch (msg->Code)
246 * Left-Amiga+V?
248 case 0x34:
249 if (msg->Qualifier & IEQUALIFIER_LCOMMAND)
250 id = (ihd->ihd_MaxID == 1) ? 1 : 2;
251 break;
254 * Left-Amiga+B?
256 case 0x35:
257 if (msg->Qualifier & IEQUALIFIER_LCOMMAND)
258 id = 1;
259 break;
262 * Return/Enter?
264 case 0x43:
265 case 0x44:
266 if (ihd->ihd_Request->br_Flags & BREQF_FAST_KEYS)
267 id = (ihd->ihd_MaxID == 1) ? 1 : GADGET(ihd->ihd_ReturnObj)->GadgetID;
268 break;
271 * Esc?
273 case 0x45:
274 if (ihd->ihd_Request->br_Flags & BREQF_FAST_KEYS)
275 id = 1;
276 break;
278 if (id) AsmDoMethod(window, WM_REPORT_ID, id, 0);
280 REGFUNC_END
281 static struct Hook ReqHook = { NULL, NULL, (HOOKFUNC)ReqHookFunc, NULL, NULL };
284 * Put up a BGUI requester.
286 #ifdef __AROS__
287 makearosproto
288 AROS_LH3(ULONG, BGUI_RequestA,
289 AROS_LHA(struct Window *, win, A0),
290 AROS_LHA(struct bguiRequest *, es, A1),
291 AROS_LHA(ULONG *, args, A2),
292 struct Library *, BGUIBase, 7, BGUI)
293 #else
294 makeproto SAVEDS ASM ULONG BGUI_RequestA(REG(a0) struct Window *win, REG(a1) struct bguiRequest *es, REG(a2) ULONG *args)
295 #endif
297 AROS_LIBFUNC_INIT
299 Object *window;
300 struct Screen *screen;
301 IHD ihd;
302 struct Window *wptr;
303 UBYTE *gstr, *wdt;
304 ULONG id, maxid, signal, rc = ~0;
305 APTR rlock = NULL;
306 BOOL cw = FALSE, running = TRUE;
309 * Center on the window?
311 if (( es->br_Flags & BREQF_CENTERWINDOW ) && win )
312 cw = TRUE;
315 * Get the screen.
317 screen = win ? win->WScreen : es->br_Screen;
320 * We need these strings.
322 if (es->br_TextFormat && es->br_GadgetFormat)
325 * Allocate private copy of the gadget string.
327 if (gstr = (UBYTE *)BGUI_AllocPoolMem(strlen(es->br_GadgetFormat) + 1))
330 * Copy the gadget string.
332 strcpy(gstr, es->br_GadgetFormat);
335 * Figure out requester title.
337 if (es->br_Title) wdt = es->br_Title;
338 else
340 if (win && win->Title) wdt = win->Title;
341 else
343 InitLocale();
344 wdt = LOCSTR(MSG_BGUI_REQUESTA_TITLE);
349 * Create a window object.
351 window = WindowObject,
352 WINDOW_Position, es->br_ReqPos,
353 cw ? WINDOW_PosRelBox : TAG_IGNORE, IBOX( &win->LeftEdge ),
354 WINDOW_Title, wdt,
355 WINDOW_CloseGadget, FALSE,
356 WINDOW_SizeGadget, FALSE,
357 WINDOW_RMBTrap, TRUE,
358 WINDOW_SmartRefresh, TRUE,
359 WINDOW_Font, es->br_TextAttr,
360 WINDOW_IDCMP, IDCMP_RAWKEY,
361 WINDOW_IDCMPHookBits, IDCMP_RAWKEY,
362 WINDOW_IDCMPHook, &ReqHook,
363 WINDOW_NoBufferRP, TRUE,
364 WINDOW_AutoAspect, es->br_Flags & BREQF_AUTO_ASPECT ? TRUE : FALSE,
365 WINDOW_AutoKeyLabel, TRUE,
367 screen ? WINDOW_Screen : TAG_IGNORE, screen,
369 WINDOW_MasterGroup,
370 VGroupObject, NormalHOffset, NormalVOffset, NormalSpacing,
371 es->br_Flags & BREQF_NO_PATTERN ? TAG_IGNORE : GROUP_BackFill, SHINE_RASTER,
372 StartMember,
373 InfoObject,
374 FRM_Type, FRTYPE_BUTTON,
375 FRM_Recessed, TRUE,
376 INFO_TextFormat, es->br_TextFormat,
377 INFO_FixTextWidth, TRUE,
378 INFO_FixTextHeight, TRUE,
379 INFO_Args, args,
380 INFO_HorizOffset, 10,
381 INFO_VertOffset, 6,
382 EndObject,
383 EndMember,
384 StartMember,
385 CreateButtonGroup(gstr, es->br_Flags & BREQF_XEN_BUTTONS, es->br_Underscore, &maxid, &ihd.ihd_ReturnObj),
386 LGO_FixMinHeight, TRUE,
387 EndMember,
388 EndObject,
389 EndObject;
391 if (window)
394 * Setup hook data.
396 ihd.ihd_Request = es;
397 ihd.ihd_MaxID = maxid;
398 ReqHook.h_Data = ( APTR )&ihd;
401 * Open the window and wait
402 * for a gadget click.
404 if (wptr = (struct Window *)AsmDoMethod(window, WM_OPEN))
407 * Lock parent window?
409 if ((es->br_Flags & BREQF_LOCKWINDOW) && win)
410 rlock = BGUI_LockWindow(win);
413 * Pick up signal bit.
415 Get_Attr(window, WINDOW_SigMask, &signal);
419 Wait(signal);
420 while((id = AsmDoMethod( window, WM_HANDLEIDCMP )) != WMHI_NOMORE)
423 * Gadget clicked?
425 if (id >= 1 && id <= maxid)
427 rc = id - 1;
428 running = FALSE;
431 } while (running);
432 AsmDoMethod(window, WM_CLOSE);
433 BGUI_UnlockWindow(rlock);
435 DisposeObject(window);
437 BGUI_FreePoolMem(gstr);
440 return rc;
442 AROS_LIBFUNC_EXIT