Updated Sourceforge username and host.
[tangerine.git] / rom / intuition / buildsysrequest_aros.c
blobb41f94143d9bd58edea29026267fd33cfeb018ae
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
98 INPUTS
99 window - The window in which the requester will appear
100 bodytext - The Text to be shown in the body of the requester
101 postext - The Text to be shown in the positive choice gadget
102 negtext - The Text to be shown in the negative choice gadget
103 IDCMPFlags - The IDCMP Flags for this requester
104 width, height - The dimensions of the requester
106 RESULT
108 NOTES
110 EXAMPLE
112 BUGS
114 SEE ALSO
115 FreeSysRequest(), DisplayAlert(), ModifyIDCMP(), exec.library/Wait(),
116 Request(), AutoRequest(), EasyRequestArgs(), BuildEasyRequestArgs()
118 INTERNALS
120 HISTORY
122 *****************************************************************************/
124 AROS_LIBFUNC_INIT
126 struct Screen *scr = NULL, *lockedscr = NULL;
127 struct Window *req;
128 struct Gadget *gadgets;
129 STRPTR reqtitle;
130 STRPTR gadgetlabels[3];
131 struct sysreqdims dims;
132 struct IntRequestUserData *requserdata;
134 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: window 0x%lx body <%s> postext <%s> negtext <%s> IDCMPFlags 0x%lx width %ld height %ld\n",
135 (ULONG) window,
136 bodytext ? (char *) bodytext->IText : "<NULL>",
137 (postext && postext->IText) ? (char *) postext->IText : "<NULL>",
138 (negtext && negtext->IText) ? (char *) negtext->IText : "<NULL>",
139 IDCMPFlags,
140 (LONG) width,
141 (LONG) height));
143 /* negtext and bodytest must be specified, postext is optional */
144 if (!negtext || !bodytext) return NULL;
146 /* get requester title */
148 reqtitle = NULL;
149 if (window) reqtitle = window->Title;
150 if (!reqtitle) reqtitle = "System Request"; /* stegerg: should be localized */
152 /* get screen and screendrawinfo */
153 if (window)
154 scr = window->WScreen;
155 if (!scr)
157 scr = LockPubScreen(NULL);
158 if (!scr)
159 return NULL;
160 lockedscr = scr;
163 if (postext)
165 dims.gadgets = 2;
167 gadgetlabels[0] = postext->IText;
168 gadgetlabels[1] = negtext->IText;
169 gadgetlabels[2] = NULL;
171 else
173 dims.gadgets = 1;
175 gadgetlabels[0] = negtext->IText;
176 gadgetlabels[1] = NULL;
179 /* create everything */
181 if (buildsysreq_calculatedims(&dims, scr,
182 bodytext, gadgetlabels, IntuitionBase))
184 gadgets = buildsysreq_makegadgets(&dims, gadgetlabels, scr, IntuitionBase);
185 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: gadgets 0x%lx\n", (ULONG) gadgets));
186 if (gadgets)
188 requserdata = AllocVec(sizeof(struct IntRequestUserData),
189 MEMF_ANY|MEMF_CLEAR);
190 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: requserdata 0x%lx\n", (ULONG) requserdata));
191 if (requserdata)
193 struct TagItem win_tags[] =
195 {WA_Width , dims.width },
196 {WA_Height , dims.height },
197 {WA_Left , (scr->Width/2) - (dims.width/2) },
198 {WA_Top , (scr->Height/2) - (dims.height/2) },
199 {WA_IDCMP , (IDCMP_GADGETUP | IDCMP_RAWKEY | (IDCMPFlags & ~IDCMP_VANILLAKEY))},
200 {WA_Gadgets , (IPTR)gadgets },
201 {WA_Title , (IPTR)reqtitle },
202 {(lockedscr ? WA_PubScreen : WA_CustomScreen) , (IPTR)scr },
203 {WA_Flags , WFLG_DRAGBAR |
204 WFLG_DEPTHGADGET |
205 WFLG_ACTIVATE |
206 WFLG_RMBTRAP /*|
207 WFLG_SIMPLE_REFRESH*/ },
208 {TAG_DONE }
211 req = OpenWindowTagList(NULL, win_tags);
212 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: req 0x%lx\n", (ULONG) req));
213 if (req)
215 if (lockedscr) UnlockPubScreen(NULL, lockedscr);
217 req->UserData = (BYTE *)requserdata;
218 requserdata->IDCMP = IDCMPFlags;
219 requserdata->GadgetLabels = NULL;
220 requserdata->Gadgets = gadgets;
221 requserdata->NumGadgets = dims.gadgets;
222 buildsysreq_draw(&dims, bodytext,
223 req, scr, gadgets, IntuitionBase);
224 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: gadgets 0x%lx\n", (ULONG) gadgets));
226 return req;
229 /* opening requester failed -> free everything */
230 FreeVec(requserdata);
232 intrequest_freegadgets(gadgets, IntuitionBase);
236 if (lockedscr) UnlockPubScreen(NULL, lockedscr);
238 return NULL;
240 AROS_LIBFUNC_EXIT
242 } /* BuildSysRequest */
244 /**********************************************************************************************/
246 /* draw the contents of the requester */
247 static void buildsysreq_draw(struct sysreqdims *dims, struct IntuiText *itext,
248 struct Window *req, struct Screen *scr,
249 struct Gadget *gadgets,
250 struct IntuitionBase *IntuitionBase)
252 struct TagItem frame_tags[] =
254 {IA_Left , req->BorderLeft + OUTERSPACING_X },
255 {IA_Top , req->BorderTop + OUTERSPACING_Y },
256 {IA_Width , req->Width - req->BorderLeft - req->BorderRight - OUTERSPACING_X * 2 },
257 {IA_Height , req->Height - req->BorderTop - req->BorderBottom -
258 dims->fontheight - OUTERSPACING_Y * 2 -
259 TEXTGADGETSPACING - BUTTONBORDER_Y * 2 },
260 {IA_Recessed , TRUE },
261 {IA_EdgesOnly , FALSE },
262 {TAG_DONE }
264 struct DrawInfo *dri;
265 struct Image *frame;
267 dri = GetScreenDrawInfo(scr);
268 if (!dri)
269 return;
271 SetFont(req->RPort, dri->dri_Font);
273 /* draw background pattern */
274 SetABPenDrMd(req->RPort,
275 dri->dri_Pens[SHINEPEN], dri->dri_Pens[BACKGROUNDPEN],
276 JAM1);
277 SetAfPt(req->RPort, BgPattern, 1);
278 RectFill(req->RPort, req->BorderLeft,
279 req->BorderTop,
280 req->Width - req->BorderRight,
281 req->Height - req->BorderBottom);
282 SetAfPt(req->RPort, NULL, 0);
284 /* draw textframe */
285 frame = (struct Image *)NewObjectA(NULL, FRAMEICLASS, frame_tags);
286 if (frame)
288 DrawImageState(req->RPort, frame, 0, 0, IDS_NORMAL, dri);
289 DisposeObject((Object *)frame);
292 /* draw text */
293 ReqPrintIText(scr, dri, req->RPort, itext,
294 dims->itextleft, req->BorderTop + OUTERSPACING_Y + TEXTBOXBORDER_Y,
295 IntuitionBase);
297 /* draw gadgets */
298 RefreshGList(gadgets, req, NULL, -1L);
300 FreeScreenDrawInfo(scr, dri);
303 /**********************************************************************************************/
305 /* calculate dimensions of the requester */
306 static BOOL buildsysreq_calculatedims(struct sysreqdims *dims,
307 struct Screen *scr,
308 struct IntuiText *itext,
309 STRPTR *gadgetlabels,
310 struct IntuitionBase *IntuitionBase)
313 LONG currentgadget = 0;
314 WORD itextwidth, itextheight;
315 UWORD textboxwidth = 0, gadgetswidth; /* width of upper/lower part */
317 /* calculate height of requester */
318 dims->fontheight = scr->RastPort.Font->tf_YSize;
320 ReqITextSize(scr, itext, &itextwidth, &itextheight, IntuitionBase);
322 dims->height = scr->WBorTop + dims->fontheight + 1 +
323 OUTERSPACING_Y +
324 TEXTBOXBORDER_Y +
325 itextheight +
326 TEXTBOXBORDER_Y +
327 TEXTGADGETSPACING +
328 BUTTONBORDER_Y +
329 dims->fontheight +
330 BUTTONBORDER_Y +
331 OUTERSPACING_Y +
332 scr->WBorBottom;
334 if (dims->height > scr->Height)
335 return FALSE;
337 textboxwidth = itextwidth + TEXTBOXBORDER_X * 2;
339 /* calculate width of gadgets */
340 dims->gadgetwidth = 0;
341 while (gadgetlabels[currentgadget])
343 UWORD gadgetwidth; /* width of current gadget */
345 gadgetwidth = TextLength(&scr->RastPort, gadgetlabels[currentgadget],
346 strlen(gadgetlabels[currentgadget]));
347 if (gadgetwidth > dims->gadgetwidth)
348 dims->gadgetwidth = gadgetwidth;
349 currentgadget++;
351 dims->gadgetwidth += BUTTONBORDER_X * 2;
352 gadgetswidth = (dims->gadgetwidth + GADGETGADGETSPACING) * dims->gadgets - GADGETGADGETSPACING;
354 /* calculate width of requester and req text position */
355 dims->itextleft = scr->WBorLeft + OUTERSPACING_X + TEXTBOXBORDER_X;
356 if (textboxwidth > gadgetswidth)
358 dims->width = textboxwidth;
360 else
362 dims->itextleft += (gadgetswidth - textboxwidth) / 2;
363 dims->width = gadgetswidth;
366 dims->width += OUTERSPACING_X * 2 + scr->WBorLeft + scr->WBorRight;
367 if (dims->width > scr->Width)
368 return FALSE;
370 return TRUE;
373 /**********************************************************************************************/
375 /* make all the gadgets */
376 static struct Gadget *buildsysreq_makegadgets(struct sysreqdims *dims,
377 STRPTR *gadgetlabels,
378 struct Screen *scr,
379 struct IntuitionBase *IntuitionBase)
381 struct TagItem frame_tags[] =
383 {IA_FrameType, FRAME_BUTTON },
384 {IA_Width , dims->gadgetwidth },
385 {IA_Height , dims->fontheight + BUTTONBORDER_Y * 2},
386 {TAG_DONE }
388 struct Gadget *gadgetlist, *thisgadget = NULL;
389 struct Image *gadgetframe;
390 WORD currentgadget;
391 UWORD xoffset, restwidth;
393 if (gadgetlabels[0] == NULL)
394 return NULL;
396 gadgetframe = (struct Image *)NewObjectA(NULL, FRAMEICLASS, frame_tags);
397 if (!gadgetframe)
398 return NULL;
400 restwidth = dims->width - scr->WBorLeft - scr->WBorRight - OUTERSPACING_X * 2;
401 if (dims->gadgets == 1)
402 xoffset = scr->WBorLeft + OUTERSPACING_X + (restwidth - dims->gadgetwidth) / 2;
403 else
405 xoffset = scr->WBorLeft + OUTERSPACING_X;
406 restwidth -= dims->gadgets * dims->gadgetwidth;
409 gadgetlist = NULL;
411 for (currentgadget = 0; gadgetlabels[currentgadget]; currentgadget++)
413 WORD gadgetid = (currentgadget == (dims->gadgets - 1)) ? 0 : currentgadget + 1;
414 struct TagItem gad_tags[] =
416 {GA_ID , gadgetid },
417 {GA_Previous , (IPTR)thisgadget },
418 {GA_Left , xoffset },
419 {GA_Top , dims->height -
420 scr->WBorBottom - dims->fontheight -
421 OUTERSPACING_Y - BUTTONBORDER_Y * 2 },
422 {GA_Image , (IPTR)gadgetframe },
423 {GA_RelVerify , TRUE },
424 {TAG_DONE }
426 struct TagItem gad2_tags[] =
428 {GA_Text , (IPTR)gadgetlabels[currentgadget] },
429 {TAG_DONE }
432 thisgadget = NewObjectA(NULL, FRBUTTONCLASS, gad_tags);
435 if (currentgadget == 0)
436 gadgetlist = thisgadget;
438 if (!thisgadget)
440 intrequest_freegadgets(gadgetlist, IntuitionBase);
441 return NULL;
444 SetAttrsA(thisgadget, gad2_tags);
446 if ((currentgadget + 1) != dims->gadgets)
448 xoffset += dims->gadgetwidth +
449 restwidth / (dims->gadgets - currentgadget - 1);
450 restwidth -= restwidth / (dims->gadgets - currentgadget - 1);
454 return gadgetlist;
457 /**********************************************************************************************/
459 static void ReqITextSize(struct Screen *scr, struct IntuiText *itext,
460 WORD *width, WORD *height,
461 struct IntuitionBase *IntuitionBase)
463 WORD w, h;
465 *width = 0;
466 *height = 0;
468 while(itext)
470 w = TextLength(&scr->RastPort, itext->IText, strlen(itext->IText));
471 h = scr->RastPort.Font->tf_YSize;
473 if (itext->LeftEdge > 0) w += itext->LeftEdge;
474 if (itext->TopEdge > 0) h += itext->TopEdge;
476 if (w > *width) *width = w;
477 if (h > *height) *height = h;
479 itext = itext->NextText;
483 /**********************************************************************************************/
485 static void ReqPrintIText(struct Screen *scr, struct DrawInfo *dri,
486 struct RastPort *rp, struct IntuiText *itext, WORD x, WORD y,
487 struct IntuitionBase *IntuitionBase)
489 SetDrMd(rp, JAM1);
490 SetAPen(rp, dri->dri_Pens[TEXTPEN]);
492 while(itext)
494 Move(rp, x + itext->LeftEdge,
495 y + itext->TopEdge + scr->RastPort.Font->tf_Baseline);
496 Text(rp, itext->IText, strlen(itext->IText));
498 itext = itext->NextText;
502 /**********************************************************************************************/