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
)
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
115 FreeSysRequest(), DisplayAlert(), ModifyIDCMP(), exec.library/Wait(),
116 Request(), AutoRequest(), EasyRequestArgs(), BuildEasyRequestArgs()
122 *****************************************************************************/
126 struct Screen
*scr
= NULL
, *lockedscr
= NULL
;
128 struct Gadget
*gadgets
;
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",
136 bodytext
? (char *) bodytext
->IText
: "<NULL>",
137 (postext
&& postext
->IText
) ? (char *) postext
->IText
: "<NULL>",
138 (negtext
&& negtext
->IText
) ? (char *) negtext
->IText
: "<NULL>",
143 /* negtext and bodytest must be specified, postext is optional */
144 if (!negtext
|| !bodytext
) return NULL
;
146 /* get requester title */
149 if (window
) reqtitle
= window
->Title
;
150 if (!reqtitle
) reqtitle
= "System Request"; /* stegerg: should be localized */
152 /* get screen and screendrawinfo */
154 scr
= window
->WScreen
;
157 scr
= LockPubScreen(NULL
);
167 gadgetlabels
[0] = postext
->IText
;
168 gadgetlabels
[1] = negtext
->IText
;
169 gadgetlabels
[2] = NULL
;
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
));
188 requserdata
= AllocVec(sizeof(struct IntRequestUserData
),
189 MEMF_ANY
|MEMF_CLEAR
);
190 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: requserdata 0x%lx\n", (ULONG
) 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
|
207 WFLG_SIMPLE_REFRESH*/ },
211 req
= OpenWindowTagList(NULL
, win_tags
);
212 DEBUG_BUILDSYSREQUEST(dprintf("intrequest_buildsysrequest: req 0x%lx\n", (ULONG
) 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
));
229 /* opening requester failed -> free everything */
230 FreeVec(requserdata
);
232 intrequest_freegadgets(gadgets
, IntuitionBase
);
236 if (lockedscr
) UnlockPubScreen(NULL
, lockedscr
);
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
},
264 struct DrawInfo
*dri
;
267 dri
= GetScreenDrawInfo(scr
);
271 SetFont(req
->RPort
, dri
->dri_Font
);
273 /* draw background pattern */
274 SetABPenDrMd(req
->RPort
,
275 dri
->dri_Pens
[SHINEPEN
], dri
->dri_Pens
[BACKGROUNDPEN
],
277 SetAfPt(req
->RPort
, BgPattern
, 1);
278 RectFill(req
->RPort
, req
->BorderLeft
,
280 req
->Width
- req
->BorderRight
,
281 req
->Height
- req
->BorderBottom
);
282 SetAfPt(req
->RPort
, NULL
, 0);
285 frame
= (struct Image
*)NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
288 DrawImageState(req
->RPort
, frame
, 0, 0, IDS_NORMAL
, dri
);
289 DisposeObject((Object
*)frame
);
293 ReqPrintIText(scr
, dri
, req
->RPort
, itext
,
294 dims
->itextleft
, req
->BorderTop
+ OUTERSPACING_Y
+ TEXTBOXBORDER_Y
,
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
,
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 +
334 if (dims
->height
> scr
->Height
)
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
;
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
;
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
)
373 /**********************************************************************************************/
375 /* make all the gadgets */
376 static struct Gadget
*buildsysreq_makegadgets(struct sysreqdims
*dims
,
377 STRPTR
*gadgetlabels
,
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},
388 struct Gadget
*gadgetlist
, *thisgadget
= NULL
;
389 struct Image
*gadgetframe
;
391 UWORD xoffset
, restwidth
;
393 if (gadgetlabels
[0] == NULL
)
396 gadgetframe
= (struct Image
*)NewObjectA(NULL
, FRAMEICLASS
, frame_tags
);
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;
405 xoffset
= scr
->WBorLeft
+ OUTERSPACING_X
;
406 restwidth
-= dims
->gadgets
* dims
->gadgetwidth
;
411 for (currentgadget
= 0; gadgetlabels
[currentgadget
]; currentgadget
++)
413 WORD gadgetid
= (currentgadget
== (dims
->gadgets
- 1)) ? 0 : currentgadget
+ 1;
414 struct TagItem gad_tags
[] =
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
},
426 struct TagItem gad2_tags
[] =
428 {GA_Text
, (IPTR
)gadgetlabels
[currentgadget
] },
432 thisgadget
= NewObjectA(NULL
, FRBUTTONCLASS
, gad_tags
);
435 if (currentgadget
== 0)
436 gadgetlist
= thisgadget
;
440 intrequest_freegadgets(gadgetlist
, IntuitionBase
);
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);
457 /**********************************************************************************************/
459 static void ReqITextSize(struct Screen
*scr
, struct IntuiText
*itext
,
460 WORD
*width
, WORD
*height
,
461 struct IntuitionBase
*IntuitionBase
)
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
)
490 SetAPen(rp
, dri
->dri_Pens
[TEXTPEN
]);
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 /**********************************************************************************************/