define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / rom / intuition / buildsysrequest_aros.c
blob89a63ffcaea729eda7ce63245230524657efc49b
1 /*
2 Copyright © 1995-2007, 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 /**********************************************************************************************/
10 #include <proto/exec.h>
11 #include <proto/intuition.h>
12 #include <proto/graphics.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <clib/macros.h>
17 #include <exec/memory.h>
18 #include <intuition/gadgetclass.h>
19 #include <intuition/imageclass.h>
20 #include <intuition/screens.h>
21 #include <graphics/rastport.h>
22 #include <graphics/gfxmacros.h>
23 #include <utility/tagitem.h>
24 #include "intuition_intern.h"
26 extern UWORD BgPattern[];
28 /**********************************************************************************************/
30 #define OUTERSPACING_X 4
31 #define OUTERSPACING_Y 4
32 #define GADGETGADGETSPACING 8
33 #define TEXTGADGETSPACING 4
34 #define TEXTBOXBORDER_X 16
35 #define TEXTBOXBORDER_Y 4
36 #define BUTTONBORDER_X 8
37 #define BUTTONBORDER_Y 4
39 /**********************************************************************************************/
41 struct sysreqdims
43 UWORD width; /* width of the requester */
44 UWORD height; /* height of the requester */
45 UWORD fontheight; /* height of the default font */
46 UWORD itextleft;
47 int gadgets; /* number of gadgets */
48 UWORD gadgetwidth; /* width of a gadget */
51 /**********************************************************************************************/
53 static BOOL buildsysreq_calculatedims(struct sysreqdims *dims,
54 struct Screen *scr,
55 struct IntuiText *itext,
56 STRPTR *gadgetlabels,
57 struct IntuitionBase *IntuitionBase);
58 static struct Gadget *buildsysreq_makegadgets(struct sysreqdims *dims,
59 STRPTR *gadgetlabels,
60 struct Screen *scr,
61 struct IntuitionBase *IntuitionBase);
62 static void buildsysreq_draw(struct sysreqdims *dims, struct IntuiText *itext,
63 struct Window *win, struct Screen *scr,
64 struct Gadget *gadgets,
65 struct IntuitionBase *IntuitionBase);
67 static void ReqITextSize(struct Screen *scr, struct IntuiText *itext,
68 WORD *width, WORD *height,
69 struct IntuitionBase *IntuitionBase);
71 static void ReqPrintIText(struct Screen *scr, struct DrawInfo *dri,
72 struct RastPort *rp, struct IntuiText *itext, WORD x, WORD y,
73 struct IntuitionBase *IntuitionBase);
75 /*****************************************************************************
77 NAME */
78 #include <proto/intuition.h>
79 #include <exec/types.h>
80 #include <intuition/intuition.h>
82 AROS_LH7(struct Window *, BuildSysRequest,
84 /* SYNOPSIS */
85 AROS_LHA(struct Window * , window, A0),
86 AROS_LHA(struct IntuiText *, bodytext, A1),
87 AROS_LHA(struct IntuiText *, postext, A2),
88 AROS_LHA(struct IntuiText *, negtext, A3),
89 AROS_LHA(ULONG , IDCMPFlags , D0),
90 AROS_LHA(WORD , width, D2),
91 AROS_LHA(WORD , height, D3),
93 /* LOCATION */
94 struct IntuitionBase *, IntuitionBase, 60, Intuition)
96 /* FUNCTION
97 Build and display a system requester.
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(), EasyRequestArgs(), BuildEasyRequestArgs()
119 INTERNALS
121 HISTORY
123 *****************************************************************************/
125 AROS_LIBFUNC_INIT
127 struct Screen *scr = NULL, *lockedscr = NULL;
128 struct Window *req;
129 struct Gadget *gadgets;
130 STRPTR reqtitle;
131 STRPTR gadgetlabels[3];
132 struct sysreqdims dims;
133 struct IntRequestUserData *requserdata;
135 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: window 0x%lx body <%s> postext <%s> negtext <%s> IDCMPFlags 0x%lx width %ld height %ld\n",
136 (ULONG) window,
137 bodytext ? (char *) bodytext->IText : "<NULL>",
138 (postext && postext->IText) ? (char *) postext->IText : "<NULL>",
139 (negtext && negtext->IText) ? (char *) negtext->IText : "<NULL>",
140 IDCMPFlags,
141 (LONG) width,
142 (LONG) height));
144 /* negtext and bodytest must be specified, postext is optional */
145 if (!negtext || !bodytext) return NULL;
147 /* get requester title */
149 reqtitle = NULL;
150 if (window) reqtitle = window->Title;
151 if (!reqtitle) reqtitle = "System Request"; /* stegerg: should be localized */
153 /* get screen and screendrawinfo */
154 if (window)
155 scr = window->WScreen;
156 if (!scr)
158 scr = LockPubScreen(NULL);
159 if (!scr)
160 return NULL;
161 lockedscr = scr;
164 if (postext)
166 dims.gadgets = 2;
168 gadgetlabels[0] = postext->IText;
169 gadgetlabels[1] = negtext->IText;
170 gadgetlabels[2] = NULL;
172 else
174 dims.gadgets = 1;
176 gadgetlabels[0] = negtext->IText;
177 gadgetlabels[1] = NULL;
180 /* create everything */
182 if (buildsysreq_calculatedims(&dims, scr,
183 bodytext, gadgetlabels, IntuitionBase))
185 gadgets = buildsysreq_makegadgets(&dims, gadgetlabels, scr, IntuitionBase);
186 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: gadgets 0x%lx\n", (ULONG) gadgets));
187 if (gadgets)
189 requserdata = AllocVec(sizeof(struct IntRequestUserData),
190 MEMF_ANY|MEMF_CLEAR);
191 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: requserdata 0x%lx\n", (ULONG) requserdata));
192 if (requserdata)
194 struct TagItem win_tags[] =
196 {WA_Width , dims.width },
197 {WA_Height , dims.height },
198 {WA_Left , (scr->Width/2) - (dims.width/2) },
199 {WA_Top , (scr->Height/2) - (dims.height/2) },
200 {WA_IDCMP , (IDCMP_GADGETUP | IDCMP_RAWKEY | (IDCMPFlags & ~IDCMP_VANILLAKEY))},
201 {WA_Gadgets , (IPTR)gadgets },
202 {WA_Title , (IPTR)reqtitle },
203 {(lockedscr ? WA_PubScreen : WA_CustomScreen) , (IPTR)scr },
204 {WA_Flags , WFLG_DRAGBAR |
205 WFLG_DEPTHGADGET |
206 WFLG_ACTIVATE |
207 WFLG_RMBTRAP /*|
208 WFLG_SIMPLE_REFRESH*/ },
209 {TAG_DONE }
212 req = OpenWindowTagList(NULL, win_tags);
213 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: req 0x%lx\n", (ULONG) req));
214 if (req)
216 if (lockedscr) UnlockPubScreen(NULL, lockedscr);
218 req->UserData = (BYTE *)requserdata;
219 requserdata->IDCMP = IDCMPFlags;
220 requserdata->GadgetLabels = NULL;
221 requserdata->Gadgets = gadgets;
222 requserdata->NumGadgets = dims.gadgets;
223 buildsysreq_draw(&dims, bodytext,
224 req, scr, gadgets, IntuitionBase);
225 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: gadgets 0x%lx\n", (ULONG) gadgets));
227 return req;
230 /* opening requester failed -> free everything */
231 FreeVec(requserdata);
233 intrequest_freegadgets(gadgets, IntuitionBase);
237 if (lockedscr) UnlockPubScreen(NULL, lockedscr);
239 return NULL;
241 AROS_LIBFUNC_EXIT
243 } /* BuildSysRequest */
245 /**********************************************************************************************/
247 /* draw the contents of the requester */
248 static void buildsysreq_draw(struct sysreqdims *dims, struct IntuiText *itext,
249 struct Window *req, struct Screen *scr,
250 struct Gadget *gadgets,
251 struct IntuitionBase *IntuitionBase)
253 struct TagItem frame_tags[] =
255 {IA_Left , req->BorderLeft + OUTERSPACING_X },
256 {IA_Top , req->BorderTop + OUTERSPACING_Y },
257 {IA_Width , req->Width - req->BorderLeft - req->BorderRight - OUTERSPACING_X * 2 },
258 {IA_Height , req->Height - req->BorderTop - req->BorderBottom -
259 dims->fontheight - OUTERSPACING_Y * 2 -
260 TEXTGADGETSPACING - BUTTONBORDER_Y * 2 },
261 {IA_Recessed , TRUE },
262 {IA_EdgesOnly , FALSE },
263 {TAG_DONE }
265 struct DrawInfo *dri;
266 struct Image *frame;
268 dri = GetScreenDrawInfo(scr);
269 if (!dri)
270 return;
272 SetFont(req->RPort, dri->dri_Font);
274 /* draw background pattern */
275 SetABPenDrMd(req->RPort,
276 dri->dri_Pens[SHINEPEN], dri->dri_Pens[BACKGROUNDPEN],
277 JAM1);
278 SetAfPt(req->RPort, BgPattern, 1);
279 RectFill(req->RPort, req->BorderLeft,
280 req->BorderTop,
281 req->Width - req->BorderRight,
282 req->Height - req->BorderBottom);
283 SetAfPt(req->RPort, NULL, 0);
285 /* draw textframe */
286 frame = (struct Image *)NewObjectA(NULL, FRAMEICLASS, frame_tags);
287 if (frame)
289 DrawImageState(req->RPort, frame, 0, 0, IDS_NORMAL, dri);
290 DisposeObject((Object *)frame);
293 /* draw text */
294 ReqPrintIText(scr, dri, req->RPort, itext,
295 dims->itextleft, req->BorderTop + OUTERSPACING_Y + TEXTBOXBORDER_Y,
296 IntuitionBase);
298 /* draw gadgets */
299 RefreshGList(gadgets, req, NULL, -1L);
301 FreeScreenDrawInfo(scr, dri);
304 /**********************************************************************************************/
306 /* calculate dimensions of the requester */
307 static BOOL buildsysreq_calculatedims(struct sysreqdims *dims,
308 struct Screen *scr,
309 struct IntuiText *itext,
310 STRPTR *gadgetlabels,
311 struct IntuitionBase *IntuitionBase)
314 LONG currentgadget = 0;
315 WORD itextwidth, itextheight;
316 UWORD textboxwidth = 0, gadgetswidth; /* width of upper/lower part */
318 /* calculate height of requester */
319 dims->fontheight = scr->RastPort.Font->tf_YSize;
321 ReqITextSize(scr, itext, &itextwidth, &itextheight, IntuitionBase);
323 dims->height = scr->WBorTop + dims->fontheight + 1 +
324 OUTERSPACING_Y +
325 TEXTBOXBORDER_Y +
326 itextheight +
327 TEXTBOXBORDER_Y +
328 TEXTGADGETSPACING +
329 BUTTONBORDER_Y +
330 dims->fontheight +
331 BUTTONBORDER_Y +
332 OUTERSPACING_Y +
333 scr->WBorBottom;
335 if (dims->height > scr->Height)
336 return FALSE;
338 textboxwidth = itextwidth + TEXTBOXBORDER_X * 2;
340 /* calculate width of gadgets */
341 dims->gadgetwidth = 0;
342 while (gadgetlabels[currentgadget])
344 UWORD gadgetwidth; /* width of current gadget */
346 gadgetwidth = TextLength(&scr->RastPort, gadgetlabels[currentgadget],
347 strlen(gadgetlabels[currentgadget]));
348 if (gadgetwidth > dims->gadgetwidth)
349 dims->gadgetwidth = gadgetwidth;
350 currentgadget++;
352 dims->gadgetwidth += BUTTONBORDER_X * 2;
353 gadgetswidth = (dims->gadgetwidth + GADGETGADGETSPACING) * dims->gadgets - GADGETGADGETSPACING;
355 /* calculate width of requester and req text position */
356 dims->itextleft = scr->WBorLeft + OUTERSPACING_X + TEXTBOXBORDER_X;
357 if (textboxwidth > gadgetswidth)
359 dims->width = textboxwidth;
361 else
363 dims->itextleft += (gadgetswidth - textboxwidth) / 2;
364 dims->width = gadgetswidth;
367 dims->width += OUTERSPACING_X * 2 + scr->WBorLeft + scr->WBorRight;
368 if (dims->width > scr->Width)
369 return FALSE;
371 return TRUE;
374 /**********************************************************************************************/
376 /* make all the gadgets */
377 static struct Gadget *buildsysreq_makegadgets(struct sysreqdims *dims,
378 STRPTR *gadgetlabels,
379 struct Screen *scr,
380 struct IntuitionBase *IntuitionBase)
382 struct TagItem frame_tags[] =
384 {IA_FrameType, FRAME_BUTTON },
385 {IA_Width , dims->gadgetwidth },
386 {IA_Height , dims->fontheight + BUTTONBORDER_Y * 2},
387 {TAG_DONE }
389 struct Gadget *gadgetlist, *thisgadget = NULL;
390 struct Image *gadgetframe;
391 WORD currentgadget;
392 UWORD xoffset, restwidth;
394 if (gadgetlabels[0] == NULL)
395 return NULL;
397 gadgetframe = (struct Image *)NewObjectA(NULL, FRAMEICLASS, frame_tags);
398 if (!gadgetframe)
399 return NULL;
401 restwidth = dims->width - scr->WBorLeft - scr->WBorRight - OUTERSPACING_X * 2;
402 if (dims->gadgets == 1)
403 xoffset = scr->WBorLeft + OUTERSPACING_X + (restwidth - dims->gadgetwidth) / 2;
404 else
406 xoffset = scr->WBorLeft + OUTERSPACING_X;
407 restwidth -= dims->gadgets * dims->gadgetwidth;
410 gadgetlist = NULL;
412 for (currentgadget = 0; gadgetlabels[currentgadget]; currentgadget++)
414 WORD gadgetid = (currentgadget == (dims->gadgets - 1)) ? 0 : currentgadget + 1;
415 struct TagItem gad_tags[] =
417 {GA_ID , gadgetid },
418 {GA_Previous , (IPTR)thisgadget },
419 {GA_Left , xoffset },
420 {GA_Top , dims->height -
421 scr->WBorBottom - dims->fontheight -
422 OUTERSPACING_Y - BUTTONBORDER_Y * 2 },
423 {GA_Image , (IPTR)gadgetframe },
424 {GA_RelVerify , TRUE },
425 {TAG_DONE }
427 struct TagItem gad2_tags[] =
429 {GA_Text , (IPTR)gadgetlabels[currentgadget] },
430 {TAG_DONE }
433 thisgadget = NewObjectA(NULL, FRBUTTONCLASS, gad_tags);
436 if (currentgadget == 0)
437 gadgetlist = thisgadget;
439 if (!thisgadget)
441 intrequest_freegadgets(gadgetlist, IntuitionBase);
442 return NULL;
445 SetAttrsA(thisgadget, gad2_tags);
447 if ((currentgadget + 1) != dims->gadgets)
449 xoffset += dims->gadgetwidth +
450 restwidth / (dims->gadgets - currentgadget - 1);
451 restwidth -= restwidth / (dims->gadgets - currentgadget - 1);
455 return gadgetlist;
458 /**********************************************************************************************/
460 static void ReqITextSize(struct Screen *scr, struct IntuiText *itext,
461 WORD *width, WORD *height,
462 struct IntuitionBase *IntuitionBase)
464 WORD w, h;
466 *width = 0;
467 *height = 0;
469 while(itext)
471 w = TextLength(&scr->RastPort, itext->IText, strlen(itext->IText));
472 h = scr->RastPort.Font->tf_YSize;
474 if (itext->LeftEdge > 0) w += itext->LeftEdge;
475 if (itext->TopEdge > 0) h += itext->TopEdge;
477 if (w > *width) *width = w;
478 if (h > *height) *height = h;
480 itext = itext->NextText;
484 /**********************************************************************************************/
486 static void ReqPrintIText(struct Screen *scr, struct DrawInfo *dri,
487 struct RastPort *rp, struct IntuiText *itext, WORD x, WORD y,
488 struct IntuitionBase *IntuitionBase)
490 SetDrMd(rp, JAM1);
491 SetAPen(rp, dri->dri_Pens[TEXTPEN]);
493 while(itext)
495 Move(rp, x + itext->LeftEdge,
496 y + itext->TopEdge + scr->RastPort.Font->tf_Baseline);
497 Text(rp, itext->IText, strlen(itext->IText));
499 itext = itext->NextText;
503 /**********************************************************************************************/