Don't get OOPBase in this ugly way.
[tangerine.git] / rom / intuition / buildsysrequest_aros.c
blobccbc19e82b973dadf9d76b379ae0d08f1f682ee8
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #define DEBUG_BUILDSYSREQUEST(x) x;
9 /**********************************************************************************************/
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <proto/graphics.h>
14 #include <stdio.h>
15 #include <stdarg.h>
16 #include <string.h>
17 #include <clib/macros.h>
18 #include <exec/memory.h>
19 #include <intuition/gadgetclass.h>
20 #include <intuition/imageclass.h>
21 #include <intuition/screens.h>
22 #include <graphics/rastport.h>
23 #include <graphics/gfxmacros.h>
24 #include <utility/tagitem.h>
25 #include "intuition_intern.h"
27 extern UWORD BgPattern[];
29 /**********************************************************************************************/
31 #define OUTERSPACING_X 4
32 #define OUTERSPACING_Y 4
33 #define GADGETGADGETSPACING 8
34 #define TEXTGADGETSPACING 4
35 #define TEXTBOXBORDER_X 16
36 #define TEXTBOXBORDER_Y 4
37 #define BUTTONBORDER_X 8
38 #define BUTTONBORDER_Y 4
40 /**********************************************************************************************/
42 struct sysreqdims
44 UWORD width; /* width of the requester */
45 UWORD height; /* height of the requester */
46 UWORD fontheight; /* height of the default font */
47 UWORD itextleft;
48 int gadgets; /* number of gadgets */
49 UWORD gadgetwidth; /* width of a gadget */
52 /**********************************************************************************************/
54 static BOOL buildsysreq_calculatedims(struct sysreqdims *dims,
55 struct Screen *scr,
56 struct IntuiText *itext,
57 STRPTR *gadgetlabels,
58 struct IntuitionBase *IntuitionBase);
59 static struct Gadget *buildsysreq_makegadgets(struct sysreqdims *dims,
60 STRPTR *gadgetlabels,
61 struct Screen *scr,
62 struct IntuitionBase *IntuitionBase);
63 static void buildsysreq_draw(struct sysreqdims *dims, struct IntuiText *itext,
64 struct Window *win, struct Screen *scr,
65 struct Gadget *gadgets,
66 struct IntuitionBase *IntuitionBase);
68 static void ReqITextSize(struct Screen *scr, struct IntuiText *itext,
69 WORD *width, WORD *height,
70 struct IntuitionBase *IntuitionBase);
72 static void ReqPrintIText(struct Screen *scr, struct DrawInfo *dri,
73 struct RastPort *rp, struct IntuiText *itext, WORD x, WORD y,
74 struct IntuitionBase *IntuitionBase);
76 /*****************************************************************************
78 NAME */
79 #include <proto/intuition.h>
80 #include <exec/types.h>
81 #include <intuition/intuition.h>
83 AROS_LH7(struct Window *, BuildSysRequest,
85 /* SYNOPSIS */
86 AROS_LHA(struct Window * , window, A0),
87 AROS_LHA(struct IntuiText *, bodytext, A1),
88 AROS_LHA(struct IntuiText *, postext, A2),
89 AROS_LHA(struct IntuiText *, negtext, A3),
90 AROS_LHA(ULONG , IDCMPFlags , D0),
91 AROS_LHA(WORD , width, D2),
92 AROS_LHA(WORD , height, D3),
94 /* LOCATION */
95 struct IntuitionBase *, IntuitionBase, 60, Intuition)
97 /* FUNCTION
99 INPUTS
100 window - The window in which the requester will appear
101 bodytext - The Text to be shown in the body of the requester
102 postext - The Text to be shown in the positive choice gadget
103 negtext - The Text to be shown in the negative choice gadget
104 IDCMPFlags - The IDCMP Flags for this requester
105 width, height - The dimensions of the requester
107 RESULT
109 NOTES
111 EXAMPLE
113 BUGS
115 SEE ALSO
116 FreeSysRequest(), DisplayAlert(), ModifyIDCMP(), exec-library/Wait(),
117 Request(), AutoRequest(), EasyRequest(), BuildEasyRequestArgs()
119 INTERNALS
121 HISTORY
123 *****************************************************************************/
125 AROS_LIBFUNC_INIT
126 AROS_LIBBASE_EXT_DECL(struct IntuitionBase *,IntuitionBase)
128 struct Screen *scr = NULL, *lockedscr = NULL;
129 struct Window *req;
130 struct Gadget *gadgets;
131 STRPTR reqtitle;
132 STRPTR gadgetlabels[3];
133 struct sysreqdims dims;
134 struct IntRequestUserData *requserdata;
136 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: window 0x%lx body <%s> postext <%s> negtext <%s> IDCMPFlags 0x%lx width %ld height %ld\n",
137 (ULONG) window,
138 bodytext ? (char *) bodytext->IText : "<NULL>",
139 (postext && postext->IText) ? (char *) postext->IText : "<NULL>",
140 (negtext && negtext->IText) ? (char *) negtext->IText : "<NULL>",
141 IDCMPFlags,
142 (LONG) width,
143 (LONG) height));
145 /* negtext and bodytest must be specified, postext is optional */
146 if (!negtext || !bodytext) return NULL;
148 /* get requester title */
150 reqtitle = NULL;
151 if (window) reqtitle = window->Title;
152 if (!reqtitle) reqtitle = "System Request"; /* stegerg: should be localized */
154 /* get screen and screendrawinfo */
155 if (window)
156 scr = window->WScreen;
157 if (!scr)
159 scr = LockPubScreen(NULL);
160 if (!scr)
161 return NULL;
162 lockedscr = scr;
165 if (postext)
167 dims.gadgets = 2;
169 gadgetlabels[0] = postext->IText;
170 gadgetlabels[1] = negtext->IText;
171 gadgetlabels[2] = NULL;
173 else
175 dims.gadgets = 1;
177 gadgetlabels[0] = negtext->IText;
178 gadgetlabels[1] = NULL;
181 /* create everything */
183 if (buildsysreq_calculatedims(&dims, scr,
184 bodytext, gadgetlabels, IntuitionBase))
186 gadgets = buildsysreq_makegadgets(&dims, gadgetlabels, scr, IntuitionBase);
187 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: gadgets 0x%lx\n", (ULONG) gadgets));
188 if (gadgets)
190 requserdata = AllocVec(sizeof(struct IntRequestUserData),
191 MEMF_ANY|MEMF_CLEAR);
192 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: requserdata 0x%lx\n", (ULONG) requserdata));
193 if (requserdata)
195 struct TagItem win_tags[] =
197 {WA_Width , dims.width },
198 {WA_Height , dims.height },
199 {WA_Left , (scr->Width/2) - (dims.width/2) },
200 {WA_Top , (scr->Height/2) - (dims.height/2) },
201 {WA_IDCMP , (IDCMP_GADGETUP | IDCMP_RAWKEY | (IDCMPFlags & ~IDCMP_VANILLAKEY))},
202 {WA_Gadgets , (IPTR)gadgets },
203 {WA_Title , (IPTR)reqtitle },
204 {(lockedscr ? WA_PubScreen : WA_CustomScreen) , (IPTR)scr },
205 {WA_Flags , WFLG_DRAGBAR |
206 WFLG_DEPTHGADGET |
207 WFLG_ACTIVATE |
208 WFLG_RMBTRAP /*|
209 WFLG_SIMPLE_REFRESH*/ },
210 {TAG_DONE }
213 req = OpenWindowTagList(NULL, win_tags);
214 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: req 0x%lx\n", (ULONG) req));
215 if (req)
217 if (lockedscr) UnlockPubScreen(NULL, lockedscr);
219 req->UserData = (BYTE *)requserdata;
220 requserdata->IDCMP = IDCMPFlags;
221 requserdata->GadgetLabels = NULL;
222 requserdata->Gadgets = gadgets;
223 requserdata->NumGadgets = dims.gadgets;
224 buildsysreq_draw(&dims, bodytext,
225 req, scr, gadgets, IntuitionBase);
226 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: gadgets 0x%lx\n", (ULONG) gadgets));
228 return req;
231 /* opening requester failed -> free everything */
232 FreeVec(requserdata);
234 intrequest_freegadgets(gadgets, IntuitionBase);
238 if (lockedscr) UnlockPubScreen(NULL, lockedscr);
240 return NULL;
242 AROS_LIBFUNC_EXIT
244 } /* BuildSysRequest */
246 /**********************************************************************************************/
248 /* draw the contents of the requester */
249 static void buildsysreq_draw(struct sysreqdims *dims, struct IntuiText *itext,
250 struct Window *req, struct Screen *scr,
251 struct Gadget *gadgets,
252 struct IntuitionBase *IntuitionBase)
254 struct TagItem frame_tags[] =
256 {IA_Left , req->BorderLeft + OUTERSPACING_X },
257 {IA_Top , req->BorderTop + OUTERSPACING_Y },
258 {IA_Width , req->Width - req->BorderLeft - req->BorderRight - OUTERSPACING_X * 2 },
259 {IA_Height , req->Height - req->BorderTop - req->BorderBottom -
260 dims->fontheight - OUTERSPACING_Y * 2 -
261 TEXTGADGETSPACING - BUTTONBORDER_Y * 2 },
262 {IA_Recessed , TRUE },
263 {IA_EdgesOnly , FALSE },
264 {TAG_DONE }
266 struct DrawInfo *dri;
267 struct Image *frame;
269 dri = GetScreenDrawInfo(scr);
270 if (!dri)
271 return;
273 SetFont(req->RPort, dri->dri_Font);
275 /* draw background pattern */
276 SetABPenDrMd(req->RPort,
277 dri->dri_Pens[SHINEPEN], dri->dri_Pens[BACKGROUNDPEN],
278 JAM1);
279 SetAfPt(req->RPort, BgPattern, 1);
280 RectFill(req->RPort, req->BorderLeft,
281 req->BorderTop,
282 req->Width - req->BorderRight,
283 req->Height - req->BorderBottom);
284 SetAfPt(req->RPort, NULL, 0);
286 /* draw textframe */
287 frame = (struct Image *)NewObjectA(NULL, FRAMEICLASS, frame_tags);
288 if (frame)
290 DrawImageState(req->RPort, frame, 0, 0, IDS_NORMAL, dri);
291 DisposeObject((Object *)frame);
294 /* draw text */
295 ReqPrintIText(scr, dri, req->RPort, itext,
296 dims->itextleft, req->BorderTop + OUTERSPACING_Y + TEXTBOXBORDER_Y,
297 IntuitionBase);
299 /* draw gadgets */
300 RefreshGList(gadgets, req, NULL, -1L);
302 FreeScreenDrawInfo(scr, dri);
305 /**********************************************************************************************/
307 /* calculate dimensions of the requester */
308 static BOOL buildsysreq_calculatedims(struct sysreqdims *dims,
309 struct Screen *scr,
310 struct IntuiText *itext,
311 STRPTR *gadgetlabels,
312 struct IntuitionBase *IntuitionBase)
315 LONG currentgadget = 0;
316 WORD itextwidth, itextheight;
317 UWORD textboxwidth = 0, gadgetswidth; /* width of upper/lower part */
319 /* calculate height of requester */
320 dims->fontheight = scr->RastPort.Font->tf_YSize;
322 ReqITextSize(scr, itext, &itextwidth, &itextheight, IntuitionBase);
324 dims->height = scr->WBorTop + dims->fontheight + 1 +
325 OUTERSPACING_Y +
326 TEXTBOXBORDER_Y +
327 itextheight +
328 TEXTBOXBORDER_Y +
329 TEXTGADGETSPACING +
330 BUTTONBORDER_Y +
331 dims->fontheight +
332 BUTTONBORDER_Y +
333 OUTERSPACING_Y +
334 scr->WBorBottom;
336 if (dims->height > scr->Height)
337 return FALSE;
339 textboxwidth = itextwidth + TEXTBOXBORDER_X * 2;
341 /* calculate width of gadgets */
342 dims->gadgetwidth = 0;
343 while (gadgetlabels[currentgadget])
345 UWORD gadgetwidth; /* width of current gadget */
347 gadgetwidth = TextLength(&scr->RastPort, gadgetlabels[currentgadget],
348 strlen(gadgetlabels[currentgadget]));
349 if (gadgetwidth > dims->gadgetwidth)
350 dims->gadgetwidth = gadgetwidth;
351 currentgadget++;
353 dims->gadgetwidth += BUTTONBORDER_X * 2;
354 gadgetswidth = (dims->gadgetwidth + GADGETGADGETSPACING) * dims->gadgets - GADGETGADGETSPACING;
356 /* calculate width of requester and req text position */
357 dims->itextleft = scr->WBorLeft + OUTERSPACING_X + TEXTBOXBORDER_X;
358 if (textboxwidth > gadgetswidth)
360 dims->width = textboxwidth;
362 else
364 dims->itextleft += (gadgetswidth - textboxwidth) / 2;
365 dims->width = gadgetswidth;
368 dims->width += OUTERSPACING_X * 2 + scr->WBorLeft + scr->WBorRight;
369 if (dims->width > scr->Width)
370 return FALSE;
372 return TRUE;
375 /**********************************************************************************************/
377 /* make all the gadgets */
378 static struct Gadget *buildsysreq_makegadgets(struct sysreqdims *dims,
379 STRPTR *gadgetlabels,
380 struct Screen *scr,
381 struct IntuitionBase *IntuitionBase)
383 struct TagItem frame_tags[] =
385 {IA_FrameType, FRAME_BUTTON },
386 {IA_Width , dims->gadgetwidth },
387 {IA_Height , dims->fontheight + BUTTONBORDER_Y * 2},
388 {TAG_DONE }
390 struct Gadget *gadgetlist, *thisgadget = NULL;
391 struct Image *gadgetframe;
392 WORD currentgadget;
393 UWORD xoffset, restwidth;
395 if (gadgetlabels[0] == NULL)
396 return NULL;
398 gadgetframe = (struct Image *)NewObjectA(NULL, FRAMEICLASS, frame_tags);
399 if (!gadgetframe)
400 return NULL;
402 restwidth = dims->width - scr->WBorLeft - scr->WBorRight - OUTERSPACING_X * 2;
403 if (dims->gadgets == 1)
404 xoffset = scr->WBorLeft + OUTERSPACING_X + (restwidth - dims->gadgetwidth) / 2;
405 else
407 xoffset = scr->WBorLeft + OUTERSPACING_X;
408 restwidth -= dims->gadgets * dims->gadgetwidth;
411 gadgetlist = NULL;
413 for (currentgadget = 0; gadgetlabels[currentgadget]; currentgadget++)
415 WORD gadgetid = (currentgadget == (dims->gadgets - 1)) ? 0 : currentgadget + 1;
416 struct TagItem gad_tags[] =
418 {GA_ID , gadgetid },
419 {GA_Previous , (IPTR)thisgadget },
420 {GA_Left , xoffset },
421 {GA_Top , dims->height -
422 scr->WBorBottom - dims->fontheight -
423 OUTERSPACING_Y - BUTTONBORDER_Y * 2 },
424 {GA_Image , (IPTR)gadgetframe },
425 {GA_RelVerify , TRUE },
426 {TAG_DONE }
428 struct TagItem gad2_tags[] =
430 {GA_Text , (IPTR)gadgetlabels[currentgadget] },
431 {TAG_DONE }
434 thisgadget = NewObjectA(NULL, FRBUTTONCLASS, gad_tags);
437 if (currentgadget == 0)
438 gadgetlist = thisgadget;
440 if (!thisgadget)
442 intrequest_freegadgets(gadgetlist, IntuitionBase);
443 return NULL;
446 SetAttrsA(thisgadget, gad2_tags);
448 if ((currentgadget + 1) != dims->gadgets)
450 xoffset += dims->gadgetwidth +
451 restwidth / (dims->gadgets - currentgadget - 1);
452 restwidth -= restwidth / (dims->gadgets - currentgadget - 1);
456 return gadgetlist;
459 /**********************************************************************************************/
461 static void ReqITextSize(struct Screen *scr, struct IntuiText *itext,
462 WORD *width, WORD *height,
463 struct IntuitionBase *IntuitionBase)
465 WORD w, h;
467 *width = 0;
468 *height = 0;
470 while(itext)
472 w = TextLength(&scr->RastPort, itext->IText, strlen(itext->IText));
473 h = scr->RastPort.Font->tf_YSize;
475 if (itext->LeftEdge > 0) w += itext->LeftEdge;
476 if (itext->TopEdge > 0) h += itext->TopEdge;
478 if (w > *width) *width = w;
479 if (h > *height) *height = h;
481 itext = itext->NextText;
485 /**********************************************************************************************/
487 static void ReqPrintIText(struct Screen *scr, struct DrawInfo *dri,
488 struct RastPort *rp, struct IntuiText *itext, WORD x, WORD y,
489 struct IntuitionBase *IntuitionBase)
491 SetDrMd(rp, JAM1);
492 SetAPen(rp, dri->dri_Pens[TEXTPEN]);
494 while(itext)
496 Move(rp, x + itext->LeftEdge,
497 y + itext->TopEdge + scr->RastPort.Font->tf_Baseline);
498 Text(rp, itext->IText, strlen(itext->IText));
500 itext = itext->NextText;
504 /**********************************************************************************************/