2 Copyright © 1995-2003, 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 /**********************************************************************************************/
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <proto/graphics.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 /**********************************************************************************************/
44 UWORD width
; /* width of the requester */
45 UWORD height
; /* height of the requester */
46 UWORD fontheight
; /* height of the default font */
48 int gadgets
; /* number of gadgets */
49 UWORD gadgetwidth
; /* width of a gadget */
52 /**********************************************************************************************/
54 static BOOL
buildsysreq_calculatedims(struct sysreqdims
*dims
,
56 struct IntuiText
*itext
,
58 struct IntuitionBase
*IntuitionBase
);
59 static struct Gadget
*buildsysreq_makegadgets(struct sysreqdims
*dims
,
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 /*****************************************************************************
79 #include <proto/intuition.h>
80 #include <exec/types.h>
81 #include <intuition/intuition.h>
83 AROS_LH7(struct Window
*, BuildSysRequest
,
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
),
95 struct IntuitionBase
*, IntuitionBase
, 60, Intuition
)
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(), EasyRequest(), BuildEasyRequestArgs()
123 *****************************************************************************/
126 AROS_LIBBASE_EXT_DECL(struct IntuitionBase
*,IntuitionBase
)
128 struct Screen
*scr
= NULL
, *lockedscr
= NULL
;
130 struct Gadget
*gadgets
;
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",
138 bodytext
? (char *) bodytext
->IText
: "<NULL>",
139 (postext
&& postext
->IText
) ? (char *) postext
->IText
: "<NULL>",
140 (negtext
&& negtext
->IText
) ? (char *) negtext
->IText
: "<NULL>",
145 /* negtext and bodytest must be specified, postext is optional */
146 if (!negtext
|| !bodytext
) return NULL
;
148 /* get requester title */
151 if (window
) reqtitle
= window
->Title
;
152 if (!reqtitle
) reqtitle
= "System Request"; /* stegerg: should be localized */
154 /* get screen and screendrawinfo */
156 scr
= window
->WScreen
;
159 scr
= LockPubScreen(NULL
);
169 gadgetlabels
[0] = postext
->IText
;
170 gadgetlabels
[1] = negtext
->IText
;
171 gadgetlabels
[2] = NULL
;
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
));
190 requserdata
= AllocVec(sizeof(struct IntRequestUserData
),
191 MEMF_ANY
|MEMF_CLEAR
);
192 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: requserdata 0x%lx\n", (ULONG
) 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
|
209 WFLG_SIMPLE_REFRESH*/ },
213 req
= OpenWindowTagList(NULL
, win_tags
);
214 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: req 0x%lx\n", (ULONG
) 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
));
231 /* opening requester failed -> free everything */
232 FreeVec(requserdata
);
234 intrequest_freegadgets(gadgets
, IntuitionBase
);
238 if (lockedscr
) UnlockPubScreen(NULL
, lockedscr
);
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
},
266 struct DrawInfo
*dri
;
269 dri
= GetScreenDrawInfo(scr
);
273 SetFont(req
->RPort
, dri
->dri_Font
);
275 /* draw background pattern */
276 SetABPenDrMd(req
->RPort
,
277 dri
->dri_Pens
[SHINEPEN
], dri
->dri_Pens
[BACKGROUNDPEN
],
279 SetAfPt(req
->RPort
, BgPattern
, 1);
280 RectFill(req
->RPort
, req
->BorderLeft
,
282 req
->Width
- req
->BorderRight
,
283 req
->Height
- req
->BorderBottom
);
284 SetAfPt(req
->RPort
, NULL
, 0);
287 frame
= (struct Image
*)NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
290 DrawImageState(req
->RPort
, frame
, 0, 0, IDS_NORMAL
, dri
);
291 DisposeObject((Object
*)frame
);
295 ReqPrintIText(scr
, dri
, req
->RPort
, itext
,
296 dims
->itextleft
, req
->BorderTop
+ OUTERSPACING_Y
+ TEXTBOXBORDER_Y
,
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
,
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 +
336 if (dims
->height
> scr
->Height
)
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
;
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
;
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
)
375 /**********************************************************************************************/
377 /* make all the gadgets */
378 static struct Gadget
*buildsysreq_makegadgets(struct sysreqdims
*dims
,
379 STRPTR
*gadgetlabels
,
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},
390 struct Gadget
*gadgetlist
, *thisgadget
= NULL
;
391 struct Image
*gadgetframe
;
393 UWORD xoffset
, restwidth
;
395 if (gadgetlabels
[0] == NULL
)
398 gadgetframe
= (struct Image
*)NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
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;
407 xoffset
= scr
->WBorLeft
+ OUTERSPACING_X
;
408 restwidth
-= dims
->gadgets
* dims
->gadgetwidth
;
413 for (currentgadget
= 0; gadgetlabels
[currentgadget
]; currentgadget
++)
415 WORD gadgetid
= (currentgadget
== (dims
->gadgets
- 1)) ? 0 : currentgadget
+ 1;
416 struct TagItem gad_tags
[] =
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
},
428 struct TagItem gad2_tags
[] =
430 {GA_Text
, (IPTR
)gadgetlabels
[currentgadget
] },
434 thisgadget
= NewObjectA(NULL
, FRBUTTONCLASS
, gad_tags
);
437 if (currentgadget
== 0)
438 gadgetlist
= thisgadget
;
442 intrequest_freegadgets(gadgetlist
, IntuitionBase
);
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);
459 /**********************************************************************************************/
461 static void ReqITextSize(struct Screen
*scr
, struct IntuiText
*itext
,
462 WORD
*width
, WORD
*height
,
463 struct IntuitionBase
*IntuitionBase
)
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
)
492 SetAPen(rp
, dri
->dri_Pens
[TEXTPEN
]);
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 /**********************************************************************************************/