2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
7 #define DEBUG_BUILDSYSREQUEST(x) x;
9 /**********************************************************************************************/
10 #include <proto/exec.h>
11 #include <proto/intuition.h>
12 #include <proto/graphics.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 /**********************************************************************************************/
43 UWORD width
; /* width of the requester */
44 UWORD height
; /* height of the requester */
45 UWORD fontheight
; /* height of the default font */
47 int gadgets
; /* number of gadgets */
48 UWORD gadgetwidth
; /* width of a gadget */
51 /**********************************************************************************************/
53 static BOOL
buildsysreq_calculatedims(struct sysreqdims
*dims
,
55 struct IntuiText
*itext
,
57 struct IntuitionBase
*IntuitionBase
);
58 static struct Gadget
*buildsysreq_makegadgets(struct sysreqdims
*dims
,
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 /*****************************************************************************
78 #include <proto/intuition.h>
79 #include <exec/types.h>
80 #include <intuition/intuition.h>
82 AROS_LH7(struct Window
*, BuildSysRequest
,
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
),
94 struct IntuitionBase
*, IntuitionBase
, 60, Intuition
)
97 Build and display a system requester.
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
116 FreeSysRequest(), DisplayAlert(), ModifyIDCMP(), exec.library/Wait(),
117 Request(), AutoRequest(), EasyRequestArgs(), BuildEasyRequestArgs()
123 *****************************************************************************/
127 struct Screen
*scr
= NULL
, *lockedscr
= NULL
;
129 struct Gadget
*gadgets
;
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",
137 bodytext
? (char *) bodytext
->IText
: "<NULL>",
138 (postext
&& postext
->IText
) ? (char *) postext
->IText
: "<NULL>",
139 (negtext
&& negtext
->IText
) ? (char *) negtext
->IText
: "<NULL>",
144 /* negtext and bodytest must be specified, postext is optional */
145 if (!negtext
|| !bodytext
) return NULL
;
147 /* get requester title */
150 if (window
) reqtitle
= window
->Title
;
151 if (!reqtitle
) reqtitle
= "System Request"; /* stegerg: should be localized */
153 /* get screen and screendrawinfo */
155 scr
= window
->WScreen
;
158 scr
= LockPubScreen(NULL
);
168 gadgetlabels
[0] = postext
->IText
;
169 gadgetlabels
[1] = negtext
->IText
;
170 gadgetlabels
[2] = NULL
;
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
));
189 requserdata
= AllocVec(sizeof(struct IntRequestUserData
),
190 MEMF_ANY
|MEMF_CLEAR
);
191 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: requserdata 0x%lx\n", (ULONG
) 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
|
208 WFLG_SIMPLE_REFRESH*/ },
212 req
= OpenWindowTagList(NULL
, win_tags
);
213 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: req 0x%lx\n", (ULONG
) 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
));
230 /* opening requester failed -> free everything */
231 FreeVec(requserdata
);
233 intrequest_freegadgets(gadgets
, IntuitionBase
);
237 if (lockedscr
) UnlockPubScreen(NULL
, lockedscr
);
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
},
265 struct DrawInfo
*dri
;
268 dri
= GetScreenDrawInfo(scr
);
272 SetFont(req
->RPort
, dri
->dri_Font
);
274 /* draw background pattern */
275 SetABPenDrMd(req
->RPort
,
276 dri
->dri_Pens
[SHINEPEN
], dri
->dri_Pens
[BACKGROUNDPEN
],
278 SetAfPt(req
->RPort
, BgPattern
, 1);
279 RectFill(req
->RPort
, req
->BorderLeft
,
281 req
->Width
- req
->BorderRight
,
282 req
->Height
- req
->BorderBottom
);
283 SetAfPt(req
->RPort
, NULL
, 0);
286 frame
= (struct Image
*)NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
289 DrawImageState(req
->RPort
, frame
, 0, 0, IDS_NORMAL
, dri
);
290 DisposeObject((Object
*)frame
);
294 ReqPrintIText(scr
, dri
, req
->RPort
, itext
,
295 dims
->itextleft
, req
->BorderTop
+ OUTERSPACING_Y
+ TEXTBOXBORDER_Y
,
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
,
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 +
335 if (dims
->height
> scr
->Height
)
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
;
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
;
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
)
374 /**********************************************************************************************/
376 /* make all the gadgets */
377 static struct Gadget
*buildsysreq_makegadgets(struct sysreqdims
*dims
,
378 STRPTR
*gadgetlabels
,
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},
389 struct Gadget
*gadgetlist
, *thisgadget
= NULL
;
390 struct Image
*gadgetframe
;
392 UWORD xoffset
, restwidth
;
394 if (gadgetlabels
[0] == NULL
)
397 gadgetframe
= (struct Image
*)NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
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;
406 xoffset
= scr
->WBorLeft
+ OUTERSPACING_X
;
407 restwidth
-= dims
->gadgets
* dims
->gadgetwidth
;
412 for (currentgadget
= 0; gadgetlabels
[currentgadget
]; currentgadget
++)
414 WORD gadgetid
= (currentgadget
== (dims
->gadgets
- 1)) ? 0 : currentgadget
+ 1;
415 struct TagItem gad_tags
[] =
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
},
427 struct TagItem gad2_tags
[] =
429 {GA_Text
, (IPTR
)gadgetlabels
[currentgadget
] },
433 thisgadget
= NewObjectA(NULL
, FRBUTTONCLASS
, gad_tags
);
436 if (currentgadget
== 0)
437 gadgetlist
= thisgadget
;
441 intrequest_freegadgets(gadgetlist
, IntuitionBase
);
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);
458 /**********************************************************************************************/
460 static void ReqITextSize(struct Screen
*scr
, struct IntuiText
*itext
,
461 WORD
*width
, WORD
*height
,
462 struct IntuitionBase
*IntuitionBase
)
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
)
491 SetAPen(rp
, dri
->dri_Pens
[TEXTPEN
]);
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 /**********************************************************************************************/